阅读这个问题时,我试图对创建一个充满零的数组的代码进行修改:
Array.apply(null, Array(10)).map(Number.prototype.valueOf,0);
相反,我想使用fill
,并更好地理解map
函数在Javascript中的用法。使用Chrome中的开发工具,我执行了以下操作,得到了一个错误:
Array.apply(null, Array(10)).fill(0).map(Number.prototype.valueOf);
Uncaught TypeError: Number.prototype.valueOf is not generic
根据我对map函数的理解,它使用该值作为参数对数组的每个值执行回调。数组是使用Array.apply(null, Array(10)).fill(0)
正确创建的,所以它应该执行Number.prototype.valueOf(0)
,为什么它会给出错误?
所以它应该执行
Number.prototype.valueOf(0)
,为什么它会给出错误?
没有。如果不将(undefined
)this
参数传递给map
,则调用map
回调,并将数组元素、索引和数组作为参数。所以它实际上称
Number.prototype.valueOf.call(undefined, 0, 0, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
但必须在数字或Number
实例上调用valueOf
,否则它将抛出。
根据MDN,map
方法接受两个参数,第二个是Value to use as this when executing callback
。所以当你打电话时:
Array.apply(null, Array(10)).map(Number.prototype.valueOf,0);
您实际上调用了Number.prototype.valueOf.call(0)
,它总是返回0。如您所知,如果map
接受一个始终返回0的函数,它将创建一个填充有0的数组。
如果你删除下面的第二个参数:
Array.apply(null, Array(10)).map(Number.prototype.valueOf);
它抛出:
Uncaught TypeError: Number.prototype.valueOf is not generic(...)
您可以弄清楚环境中map
的默认this
是什么:
[0].map(v=>{console.log(this);}) // =>Window for chrome developer tools
所以试试这个:
Number.prototype.valueOf.call(window)
您可能会得到相同的错误信息。
map
的第二个参数用作this
。在第一种情况下,每次this
都是编号0
(转换为对象Number(0)
)
因此,map
函数正在调用Number.prototype.valueOf
,而this
是Number(0)
。这实际上与Number(0).valueOf()
相同,后者自然是数字0
。
(不是Number.prototype.valueOf(0)
-试着拨打Number.prototype.valueOf(1)
,看看会得到什么)
同时,如果不将this
参数传递给map()
,则它将被设置为window
。这意味着您实际上是在window
上调用Number.prototype.valueOf
。这毫无意义,因此抛出了一个错误。0
是自变量并不重要,因为Number.prototype.valueOf()
不接受自变量。Number(0).valueOf(1)
返回0
,因为参数被完全忽略。