map
map会创建一个新数组,内容是原数组元素执行给定函数后的值
第一个参数是函数,它接收三个参数,分别是当前元素,索引和原数组,第二个参数是函数执行时内部的 this
一道面试题
["1", "2", "3"].map(parseInt)
// [1,NaN,NaN]
导致如此结果,原因有以下两点:
- map 的 callback 会被自动传入三个参数(当前元素,索引,数组本身)
- 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 才会从第一个元素开始