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

栏目: 编程语言 · 发布时间: 5年前

内容简介:继上一篇实现了自己的

继上一篇 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(此例的 thiswindow ,而且还改变不了, 也就是说 { 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 ]

复制代码

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


以上所述就是小编给大家介绍的《JS Array.reduce 实现 Array.map 和 Array.filter》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Practical JavaScript, DOM Scripting and Ajax Projects

Practical JavaScript, DOM Scripting and Ajax Projects

Frank Zammetti / Apress / April 16, 2007 / $44.99

http://www.amazon.com/exec/obidos/tg/detail/-/1590598164/ Book Description Practical JavaScript, DOM, and Ajax Projects is ideal for web developers already experienced in JavaScript who want to ......一起来看看 《Practical JavaScript, DOM Scripting and Ajax Projects》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

URL 编码/解码
URL 编码/解码

URL 编码/解码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器