首页  >  问答  >  正文

像 .map() 这样的高阶函数在 JavaScript 内部是如何工作的?

<p>现在每个人都试图使用这些高阶函数来通过编写更少的代码来获得有希望的结果。但我想知道这些函数内部是如何工作的。</p> <p>假设我写了类似的东西</p> <p> <pre class="brush:js;toolbar:false;">var numbers = [16, 25, 36]; var results = numbers.map(Math.sqrt); console.log(results); // [4, 5, 6]</pre> </p> <p>我知道“number”数组的每个元素都在逐一迭代,但是<em>如何</em>?</p> <p>我试图寻找它,但尚未得到满意的答案。</p>
P粉107772015P粉107772015422 天前405

全部回复(2)我来回复

  • P粉505450505

    P粉5054505052023-08-26 14:30:37

    我想每个供应商都应该按照 规格

    实际实现(例如 V8)可能有点复杂,请参阅此答案作为开始。您也可以参考 github 中的 v8 源码,但孤立地理解其中的一部分可能并不容易。

    引用上面的答案:

    ES2015 规范:

    1. O为ToObject(this值)。
    2. ReturnIfAbrupt(O)。
    3. len 为 ToLength(Get(O, "length"))。
    4. ReturnIfAbrupt(len)。
    5. 如果 IsCallable(callbackfn) 为 false,则抛出 TypeError 异常。
    6. 如果提供了 thisArg,则令 TthisArg;否则让T未定义
    7. A 为 ArraySpeciesCreate(O, len)。
    8. ReturnIfAbrupt(A)。
    9. k为0。
    10. 重复,同时 k < < len
      1. Pk为ToString(k)。
      2. kPresent为HasProperty(O, Pk)。
      3. ReturnIfAbrupt(kPresent)。
      4. 如果kPresenttrue,则
        1. kValue为Get(O, Pk)。
        2. ReturnIfAbrupt(kValue)。
        3. mappedValue为Call(callbackfn, T, «kValue, k >,»。
        4. ReturnIfAbrupt(mappedValue)。
        5. 状态为CreateDataPropertyOrThrow(APkmappedValue)。
        6. ReturnIfAbrupt(状态)。
      5. k增加1。
    11. 返回A

    回复
    0
  • P粉333395496

    P粉3333954962023-08-26 09:51:45

    .map 只是一个接受回调、为数组的每个项目调用回调并将值分配给新数组的方法。没什么特别的。您甚至可以自己轻松实现:

    Array.prototype.myMap = function(callback) {
      const newArr = [];
      for (let i = 0; i < this.length; i++) {
        newArr.push(callback(this[i], i, this));
      }
      return newArr;
    }
    
    var numbers = [16, 25, 36];
    var results = numbers.myMap(Math.sqrt);
    console.log(results); // [4, 5, 6]

    回复
    0
  • 取消回复