未加星标

JS Array.reduce 实现 Array.map 和 Array.filter

字体大小 | |
[前端(javascript) 所属分类 前端(javascript) | 发布者 店小二04 | 时间 2018 | 作者 红领巾 ] 0人收藏点击收藏

继上一篇 Array.prototype.reduce 后,我立志要好好学习。琢磨了很久,再加上最近看了几篇"JS 函数式编程"的文章和书籍后,然后有感而发写下了这篇文章。

Array.prototype.map 方法相信大家都用的很熟悉了,同时我也相信很多人已经自己实现了 map 函数。没有实现过自己的 map ? 没关系,我们先用 for 循环来实现下。

Array.prototype.selfMap = function () { const ary = this const result = [] const [ fn, thisArg ] = [].slice.call(arguments) if (typeof fn !== 'function') { throw new TypeError(fn + 'is not a function') } for (let i = 0; i < ary.length; i++) { result.push(fn.call(thisArg, ary[i], i, ary)) } return result } const a = new Array(1, 2, 3, 4) a.selfMap(item => item + 1) // [ 2, 3, 4, 5 ] 复制代码

实现了自己的 map ,还不是美滋滋。

但是,这和本文没有半点关系,因为我是要用 reduce 实现 map 啊

众所周知, map 函数需要传一个函数的,还有一个可选的 this 参数,但是我发现第二个参数大家很少用到,也不怎么注意,我也是这样。

[1, 2, 3].map(function(item) { console.log(this) return item }, { msg: 'mapping' }) 复制代码

上面:point_up_2:这段代码块不仅会返回一个新的数组,还会在控制台打印三次

{ msg: 'mapping' } 复制代码

有图有真相:point_down:


JS Array.reduce 实现 Array.map 和 Array.filter

可能有的小伙伴在验证我上面的例子时,会使用 箭头函数 ,然后发现总是打印 window ,就是下面这样:point_down:


JS Array.reduce 实现 Array.map 和 Array.filter

然后心里暗道“无耻小儿,竟敢骗我”。心里苦啊,箭头函数在声明时就绑定了它外层的this(此例的 this 为 window ,而且还改变不了, 也就是说 { msg: 'mapping' } 相当于白传了):sob:

似乎废话有点多额,那我们先用 reduce 来实现 map 吧(默认运行环境支持 Array.prototype.reduce ,如果不支持的话,那还写个:hammer:)

// 这次不把方法写在Array的原型上 const reduceMap = (fn, thisArg /*真想去掉thisArg这个参数*/ ) => { return (list) => { // 不怎么愿意写下面这两个判断条件 if (typeof fn !== 'function') { throw new TypeError(fn + 'is not a function') } if (!Array.isArray(list)) { throw new TypeError('list must be a Array') } if (list.length === 0) return [] return list.reduce((acc, value, index) => { acc.push(fn.call(thisArg, value, index, list)) return acc }, []) } } // 来使用下怎么样 reduceMap(x => x + 1)([ 1, 2, 3 ]) // [ 2, 3, 4 ] const mapAry1 = reduceMap(function(item) { console.log(this) return item + 1 }, { msg: 'mapping' })([ 1, 2, 3 ]) // [ 2, 3, 4 ] // logging { msg: 'mapping' } three times 复制代码

:point_up_2:实现的原理相信大家应该都懂吧。

打铁当趁热,继续来实现 filter 吧。

for 循环实现版 Array.prototype.selfFilter = function () { const ary = this const result = [] const [ fn , thisArg ] = [].slice.call(arguments) if (typeof fn !== 'function') { throw new TypeError(fn + 'is not a function') } for (let i = 0; i < ary.length; i++) { if (fn.call(thisArg, ary[i], i, ary)) { result.push(ary[i]) } } return result } const a = new Array(1, 2, 3) a.selfFilter(item => item % 2 === 0) // [ 2 ] a.selfFilter(function (item) { console.log(this) return item % 2 === 0 }) // [ 2 ] // logging {} three times 复制代码 reduce 实现版 // 同map, 不定义在Array的原型上 const reduceFilter = (fn, thisAry /* thisAry知不知你好讨厌啊 */ ) => { return (list) => { if (typeof fn !== 'function') { throw new TypeError(fn + 'is not a function') } if (!Array.isArray(list)) { throw new TypeError('list must be a Array') } if (list.length === 0) return [] return list.reduce((acc, value, index) => { fn.call(thisAry, value, index, list) ? acc.push(value) : null return acc }, []) } } reduceFilter(x => x % 2 === 0)([ 1, 2, 3 ]) // [ 2 ] 复制代码

文章里掺杂了些许 函数式编程 里面的东西,因为我也才开始学函数式编程不久,就不在大佬们面前献丑了。如果文章里有哪里写的不对或者不够准确,亦或者是觉得有写的不好的地方,烦请各位指正,也让我改正。

本文前端(javascript)相关术语:javascript是什么意思 javascript下载 javascript权威指南 javascript基础教程 javascript 正则表达式 javascript设计模式 javascript高级程序设计 精通javascript javascript教程

代码区博客精选文章
分页:12
转载请注明
本文标题:JS Array.reduce 实现 Array.map 和 Array.filter
本站链接:https://www.codesec.net/view/620955.html


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 前端(javascript) | 评论(0) | 阅读(79)