Javascript 什么是Array.map(Function.call,Number)
为什么map1的输出是[0,1,2,3],这个map函数在做什么 输入参数是映射(回调,this) 在您的示例中,您提供了函数Javascript 什么是Array.map(Function.call,Number),javascript,Javascript,为什么map1的输出是[0,1,2,3],这个map函数在做什么 输入参数是映射(回调,this) 在您的示例中,您提供了函数function.call作为映射器,它是的构造函数。函数是表示“运行此函数”的基本方式,您绑定的this是给它第一个参数 有趣的是,您给它的回调接受args(currentValue,index)。通过传递Function.call并绑定它,实际上是在强制它删除第一个参数。这是一种聪明(阅读:难以理解)的方法,可以让“Number”函数在索引上运行 e、 g.尝试[1,
function.call
作为映射器,它是的构造函数。函数是表示“运行此函数”的基本方式,您绑定的this
是给它第一个参数
有趣的是,您给它的回调接受args(currentValue,index)
。通过传递Function.call并绑定它,实际上是在强制它删除第一个参数。这是一种聪明(阅读:难以理解)的方法,可以让“Number”函数在索引上运行
e、 g.尝试[1,4,9,16].map(Function.call,String)
,您将看到相同的内容,但被解析为字符串[“1”、“4”、“9”、“16”]
让我们逐步了解第一次迭代中发生的情况,以获得更清晰的信息:
- 回调函数
,传递args函数。调用
(当前值)和1
(当前索引)0
- 此回调在执行之前绑定到第二个参数
,因此它就像调用Number
Function.call.bind(Number)(1,0)
的第一个参数是“绑定到此上下文”,但上面显式的Function.call
调用会覆盖此上下文bind
- 实际运行的是编号(0),这当然是索引
array1.map(((uu,I)=>Number(I))
(或者更好的是,Number.parseInt
,如果你想得到一个整数)
作为一名软件开发人员,这整件事读起来很酷,但我不推荐在实践中使用这种map(Function.call)
模式!如果您在自己的代码中遇到过它,至少添加一条注释,这样下一个开发人员就不需要这么做:)调用为数组的每个成员提供的函数,并返回一个新的返回值数组
在这种情况下,提供的功能是
Array.prototype.map
的第二个参数指定了所提供函数应该运行的上下文
在本例中,上下文是
Array.prototype.map
的简单实现可以大致如下:
var array1 = [1, 4, 9, 16];
map1=array1.map(Function.call,Number);
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.call(…)
有点令人费解,但它相当于在第一个参数(应该是函数)的上下文中调用call
函数。在我们的情况下,它是。这是Number
函数
然后,我们可以将此语句简化为:
(Function.call).call((Number), (1), (0), ([1, 4, 9, 16]))
// ^-- callback ^-- value ^-- array
// ^-- thisArg ^-- index
Number
函数将第一个参数转换为数字。忽略其他参数以及函数上下文。这意味着整个表达式可以简化为:
Number.call(1, 0, [1, 4, 9, 16])
其中0
是索引
这就是为什么返回值是[0,1,2,3]
,因为这些是来自原始数组的索引
不用说,原始代码示例不应该在日常编程中使用。整个系统的使用更简单:
Number(0)
即使这样,也应该注意到原始值被无用地丢弃了。此类代码示例仅在探索特定语言行为的学术意义上有用,或者在编码挑战中有意混淆朋友时有用。Array.map函数创建一个新的数组,其结果是调用提供的函数(function.call)在数组中调用Array.map的每个元素上
e、 g
当对数组中的每个值执行回调时,您将数字作为要使用的“this”值传入。在结果数组中,每个元素都是对数组中的每个值调用给定函数的结果
Function.call方法使用给定的“this”值和提供的参数调用函数。
Array.prototype.map
接受两个参数:第一个是使用数组中的每个项调用的函数,第二个很少使用的参数是使用第一个参数调用的此值。例如:
// Store an initial Array of String values
var stringArray = ['Matt','Long','JavaScript'];
// Invoke Function for each value of Array
mapResult = stringArray.map((currentValue) => {
// Concatenate and return
return currentValue + ' Software';
});
// Log map result
console.log(mapResult);
[1,2,3].map(function() { return this.x; }, {x: 3}) // returns [3,3,3]
Function.prototype.call
是所有函数上的函数:(Function
本身就是一个函数,因此Function.call
是Function.prototype.call
),它允许使用特定的this
和一组特定的参数调用函数(单独传递,在Function.prototype.apply
的情况下不作为数组传递)。例如:
// Store an initial Array of String values
var stringArray = ['Matt','Long','JavaScript'];
// Invoke Function for each value of Array
mapResult = stringArray.map((currentValue) => {
// Concatenate and return
return currentValue + ' Software';
});
// Log map result
console.log(mapResult);
[1,2,3].map(function() { return this.x; }, {x: 3}) // returns [3,3,3]
但是在真实的例子中有一个额外的细节,因为它不是做someFunction.call
,它是做Function.call
:发生的是Function.prototype.call
使用this
来确定调用什么函数:如果你重新绑定this
,就会调用另一个函数。你可以重新绑定nd这个
带有,嗯…函数。原型。调用
因此,这相当于前面的示例:
function someFunction(y) {
return this + y;
}
someFunction.call(2, 3) // Returns 5, since this=2 and y=3
对.call
的第二个调用重新绑定了第一个调用,因此它调用someFunction
而不是Function
,并将参数2和3传递给它:它归结为确切的someFunction.call(2,3)
,我们已经看到了
解释
回到真实的例子,我们可以把事情放在一起,我们有
function someFunction(y) {
return this + y;
}
Function.call.call(someFunction, 2, 3)
第二个参数进行绑定,就像.call
,因此这相当于:
[3,6,9].map(Function.call, Number)
正如我们刚才看到的,这相当于更直截了当的:
[3,6,9].map((...args) => Function.call.call(Number, ...args))
那么,现在,什么是…args
?对于每个调用,它们是数组中的项,posit
[
Number.call(3, 0, [3,6,9]),
Number.call(6, 1, [3,6,9]),
Number.call(9, 2, [3,6,9])
]
[
Number(0, [3,6,9]),
Number(1, [3,6,9]),
Number(2, [3,6,9])
]