Javascript 什么是Array.map(Function.call,Number)

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,

为什么map1的输出是[0,1,2,3],这个map函数在做什么

输入参数是映射(回调,this)

在您的示例中,您提供了函数
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])
]