结论
js数组的很多方法,其第一个参数都是 callback,而 callbak 的参数一般都是三个:element index[可选] arr[可选],在使用某个数组方法的过程中,这三个参数,无论你写不写,都会传给 arguments !
个人感觉还是比较反直觉的,因为我学到的一般是,在使用函数时,指定的命名参数会传给 arguments
,如这样
function fn() {
console.log(arguments);
}
fn(1, 2, 3);
// 输出
// Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]
fn();
// 输出
// Arguments(0) [callee: ƒ, Symbol(Symbol.iterator): ƒ]
而数组的方法实际运用过程中,会自动将其回调的三个参数全部给 arguments
。下面上代码
[1, 4, 5].filter(function () {
console.log(arguments);
})
// 输出
// Arguments(3) [1, 0, Array(3), callee: ƒ, Symbol(Symbol.iterator): ƒ]
// Arguments(3) [4, 1, Array(3), callee: ƒ, Symbol(Symbol.iterator): ƒ]
// Arguments(3) [5, 2, Array(3), callee: ƒ, Symbol(Symbol.iterator): ƒ]
filter
方法我们知道,会对每一个索引都进行判定,所以这里输出了三次。仔细观察这三次的输出,会发现 arguments
的前三个正是 element index arr
。再用 find
some
map
等方法也是一样的,这些方法的特点都是,第一个参数是回调函数,回调函数接收三个参数 element index[可选] arr[可选]
。
正文
关于这道题,网上的解答已经很多了,个人觉得这篇笔记详细:https://juejin.cn/post/7053250391948918797
对于这道题,就是要把 map
方法 和 parseInt
方法都搞清楚怎么运用就行了,其中 parseInt
的规则稍微复杂了些。这里是MDN的文档:
map
:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/map
parseInt
:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/parseInt
当然,这篇文章的主要注意力,不是放在分析这道题上,而是在解这道题的过程中,我发现的一个比较有意思的点。
在阅读上篇文章的过程中,我发现一个自己不理解的地方,parseInt
为什么能拿到 map
提供的三个参数呢?
在文章中向作者提问,他很快答复我说可以执行[1].map(function() { console.log(arguments.length) })
看看输出是不是3,答案确实是,就如开头结论的一样。但我还是不理解,因为map
方法对于callback
三个参数的描述,只有element
是必须的,[].map(parseInt)
回调参数什么都没写,长度是1才对啊。
注:此处的 element
就是 文档中的 currentValue
;MDN文档中有时用element
,有时用currentValue
,这里为了方便我就写element
。对于这点我感觉文档不是很好,既然指的是一个参数,就一直用一个词表示好了。
凭啥 map
就把 callback
的三个参数给了 arguments
?就算要给,那应该也只给个element
才对啊,index
和 arr
都是可选参数,为什么也一起赠送出去了?
于是我又继续翻看MDN,发现了这么一段话:
callback
函数会被 【自动】 传入三个参数:数组元素,元素索引,原数组本身。
第一遍看 MDN 中 map
方法时居然把它看漏了(或者看到了没在意),这下子再看就恍然大悟了!虽然index
和 arr
都是可选参数,就算我们不写,callback
也还是默认拿到了它俩。
不过,接下来我又纳闷了,这么一段话好像是第一次见,这个 “自动” ,在其他方法里好像没有这种说法,如
find
callback
函数带有 3 个参数:当前元素的值、当前元素的索引,以及数组本身。
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/find
some
callback
被调用时传入三个参数:元素的值,元素的索引,被遍历的数组。
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/some
可以看出,find
和 some
对于 callback
的描述,显然比不上 map
对于 callback
的描述那种高度。那种感觉,就像这些参数可有可无一样;需要的时候写上,不要的时候不写,它也拿不到。于是,我又去翻了英文版的MDN。好吧,感觉还不如中文版的翻译,英文文档里都没说这么一句话。
本着实践出真知的态度,我对这些方法进行了测试,然后就有了开头的结果,这些数组的方法,都会自动地把 callback
里的三个参数注入 arguments
。MDN文档也不靠谱啊
所以,parseInt
作为callback
可以拿到 map
回调提供的三个参数,这道题才会有这么个结果。
这里再补一句,MDN文档对于callback
的三个参数,感觉没写清楚。在参数描述时,说只有element
是必须的;在详细描述时,callback
来了一句含糊的描述(我感觉有些含糊,可能我是初学者的原因)。应该指明,我们在调用数组方法时可以后两个参数都是可传可不传,但是无论我们传不传,callback
都能拿到三个参数。
总结
对于 “数组的方法,会自动地把 callback
里的三个参数注入 arguments
”这个发现是有些意外的,理解了这一点后,这道题其实就很简单了。我也是今年才学前端,才疏学浅,以上有不正确的地方请指正,谢谢!