代码之家  ›  专栏  ›  技术社区  ›  william007

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

  •  10
  • william007  · 技术社区  · 8 年前
    var array1 = [1, 4, 9, 16];
    
    map1=array1.map(Function.call,Number);
    

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

    4 回复  |  直到 8 年前
        1
  •  11
  •   zzzzBov    8 年前

    Array.prototype.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
    }
    

    函数调用 和 数字 应该回来 [0, 1, 2, 3]

    当 callback ( 函数调用 thisArg ( )代码将执行以下内容:

    (Function.call).call((Number), (1), (0), ([1, 4, 9, 16]))
    //   ^-- callback               ^-- value ^-- array
    //                    ^-- thisArg    ^-- index
    

    评价 Function.call.call(...) call 第一个参数的上下文中的函数,该参数应为函数。在我们的情况下,它是。这是最重要的 数字

    然后,我们可以将此语句简化为:

    Number.call(1, 0, [1, 4, 9, 16])
    

    这个

    Number(0)
    

    哪里 0 是 index .

    [0, 1, 2, 3] ,因为这些是来自原始数组的索引。


    不用说,原始代码示例不应该在日常编程中使用。整个系统的使用更简单:

    [1, 4, 9, 16].map((value, index) => index)
    

    即使这样,也应该注意到原始值被无用地丢弃了。这些代码示例仅在探索特定语言行为的学术意义上有用,或者在编码挑战中有意混淆朋友时有用。

        2
  •  5
  •   Josh from Qaribou    8 年前

    Array#map here

    输入参数是 map(callback, this)

    在您的示例中,您提供了函数 Function.call 作为映射器,它是 Function . 函数是表示“运行此函数”的基本方式 this

    有趣的是,你给它的回调函数接受args (currentValue, index) . 通过传递Function.call并绑定它,实际上是在强制它删除第一个参数。这是一种聪明(阅读:难以理解)的方法,可以让“Number”函数在索引上运行。

    [1, 4, 9, 16].map(Function.call, String) ,您将看到相同的内容,但被解析为字符串 ["1", "4", "9", "16"]

    让我们逐步了解第一次迭代中发生的情况,以获得更清晰的信息:

    • 调用,传递参数 1 (当前值),以及 0 (当前索引)
    • Number ,在它执行之前,所以这就像调用 Function.call.bind(Number)(1, 0)
    • 第一个论点 函数调用 表示“绑定到此上下文”,但 bind
    • Number(0) ,这当然是 0

    现在,我认为大多数人会简单地使用带有第一个参数的箭头函数,他们可以忽略,例如。 array1.map((_, i) => Number(i)) (或者更好, Number.parseInt

    作为一名软件开发人员,这整件事读起来很酷,但我不推荐这样做 map(Function.call)

        3
  •  4
  •   Retsam    8 年前

    一些背景

    Array.prototype.map this

    [1,2,3].map(function() { return this.x; }, {x: 3}) // returns [3,3,3]
    

    Function.prototype.call 是一个在所有函数上都可用的函数:( Function 它本身就是一个函数,所以 Function.call Function.prototype.call 这 Function.prototype.apply )。例如:

    function someFunction(y) {
        return this + y;
    }
    someFunction.call(2, 3) // Returns 5, since this=2 and y=3
    

    但在真实的例子中有一个额外的细节,因为它不起作用 someFunction.call 函数调用 当前位置正在发生的是 正在使用 这 ,则调用另一个函数。你可以重新绑定 这 .

    因此,这相当于前面的示例:

    function someFunction(y) {
        return this + y;
    }
    Function.call.call(someFunction, 2, 3)
    

    .call 重新绑定第一个,以便调用 someFunction 而不是 作用 someFunction.call(2, 3) ,我们已经看到了。


    解释

    回到真实的例子,我们可以把事情放在一起,我们有

    [3,6,9].map(Function.call, Number)
    

    第二个参数没有绑定,就像 ,这相当于:

    [3,6,9].map((...args) => Function.call.call(Number, ...args))
    

    正如我们刚才看到的,这相当于更直截了当的:

    [3,6,9].map((...args) => Number.call(...args))
    

    那么,现在,你在做什么 ...args ? 对于每个调用,它们是数组中的项、数组中的位置以及整个数组。因此,这实际上扩展到:

    [
        Number.call(3, 0, [3,6,9]),
        Number.call(6, 1, [3,6,9]),
        Number.call(9, 2, [3,6,9])
    ]
    

    现在记住, Number.call 奥巴马的第一个论点是 这 ,而其他两个参数则提供给被调用的函数, Number 数字 不使用

    [
        Number(0, [3,6,9]),
        Number(1, [3,6,9]),
        Number(2, [3,6,9])
    ]
    

    数字 [1,2,3] . 它只是索引,不必要地被转换成数字,有很多函数是间接的。

        4
  •  0
  •   user3978398 user3978398    8 年前

    函数创建一个新数组,其结果是对数组中调用Array.map的每个元素调用提供的函数(function.call)。

    例如

    // 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);
    

    当对数组中的每个值执行回调时,您将数字作为要使用的“this”值传入。在结果数组中,每个元素都是对数组中的每个值调用给定函数的结果。

    Function.call方法使用给定的“this”值和提供的参数调用函数。