Array.prototype.map https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map调用为数组的每个成员提供的函数,并返回其返回值的新数组。
在这种情况下,提供的函数是Function.call https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call.
第二个参数Array.prototype.map
指定所提供的函数应运行的上下文。
在这种情况下,上下文是Number https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number.
一个天真的实现Array.prototype.map
看起来可能是这样的:
function map(callback, thisArg) {
const ret = []
for (let index = 0; index < this.length; index++) {
const value = this[index]
ret.push(callback.call(thisArg, value, index, this))
}
return ret
}
现在,这个特殊情况使用了很多间接,所以很难理解为什么传递Function.call
and Number
应该返回[0, 1, 2, 3]
,让我们来看看这部分。
当。。。的时候callback
(Function.call
)在上下文中被调用thisArg
(Number
)代码将执行以下内容:
(Function.call).call((Number), (1), (0), ([1, 4, 9, 16]))
// ^-- callback ^-- value ^-- array
// ^-- thisArg ^-- index
评估Function.call.call(...)
有点令人费解,但它相当于调用call
function 在第一个参数的上下文中,它应该是一个函数。就我们而言,确实如此。这是Number
功能。
然后我们可以将该语句简化为:
Number.call(1, 0, [1, 4, 9, 16])
The Number
函数将第一个参数转换为数字。其他参数以及函数上下文都将被忽略。这意味着整个表达式可以简化为:
Number(0)
where 0
是index
.
这就是为什么返回值是[0, 1, 2, 3]
,因为这些是原始数组的索引。
不用说,原始代码示例不应该在日常编程中使用。整个系统使用起来会更简单:
[1, 4, 9, 16].map((value, index) => index)
即便如此,应该指出的是,原始值被无用地丢弃了。此类代码示例仅在探索特定语言行为的学术意义上有用,或者当您想要故意迷惑您的朋友作为编码挑战的一部分时。