JS之用reduce实现map

693 阅读2分钟

map

map会创建一个新数组,内容是原数组元素执行给定函数后的值

第一个参数是函数,它接收三个参数,分别是当前元素,索引和原数组,第二个参数是函数执行时内部的 this

一道面试题

["1", "2", "3"].map(parseInt)

// [1,NaN,NaN]

导致如此结果,原因有以下两点:

  1. map 的 callback 会被自动传入三个参数(当前元素,索引,数组本身)
  2. parseInt 第二个参数 radix 如果为 undefined 、0 或未指定,会自动辨别,若字符串为 '0x' 或 '0X' 开头,radix 被指定为16;若字符串以 '0' 开头,radix被指定为 8,其余情况被指定为 10

虽然我们并没有给 callback 传入任何参数,但是按照 map 的规矩,其实已经传入了三个参数,所以函数执行过程如下:

parseInt("1", 0)  //1
parseInt("2", 1)  //NaN
parseInt("3", 2)  //NaN

第一行是因为传入 radix 为 0,parseInt 将其视为十进制数

第二行是因为当 radix 小于 2 或大于 36 时出现 NaN

第三行是因为无法将 3 视为二进制数,转化失败

修正的核心就是不要把 callback 的第二个参数 index 传入 parseInt

["1", "2", "3"].map(str=>parseInt(str))
// 让 parseInt 将元素全部视为十进制数进行解析

reduce

reduce 的第一个参数是函数,接受累计器,正在处理的元素,正在处理元素的索引以及原数组四个参数,第二个参数是初始值

用 reduce 实现 map

Array.prototype._map=function(fn,_this){
    let res=[]
    _this=_this || []
    this.reduce((pre,cur,index,arr)=>{
        return res.push(fn.call(_this,cur,index,arr))
    },[])
    return res
}
let arr=[1,2,3]
arr._map((item,index,arr)=>item*2)

这段代码的核心就是必须赋予 reduce 初始值,因为只有这样,cur 才会从第一个元素开始