【问题标题】:How do higher-order functions, like .map(), work internally in JavaScript?高阶函数(如 .map())如何在 JavaScript 内部工作?
【发布时间】:2020-04-29 20:52:12
【问题描述】:

现在每个人都试图使用这种higher-order functions 来通过编写更少的代码来获得有希望的结果。但我想知道这些函数在内部是如何工作的。

假设如果我写类似的东西

var numbers = [16, 25, 36];
var results = numbers.map(Math.sqrt);
console.log(results); // [4, 5, 6]

我知道'number'数组的每个元素都在一个一个地迭代,但是如何

我试图搜索它,但我还没有得到任何满意的答案。

【问题讨论】:

  • 看看Array.map的polyfil
  • 这是一个名为map 的函数,它被添加到类型数组中。该函数将函数作为参数,然后在遍历数组时调用该函数。然后将函数调用的返回值以数组的形式返回。
  • map 基本上像 foreach 一样用于迭代数组,这意味着它将一一获取数组的所有元素,然后对每个元素应用给定的命令/操作,然后将其推入新数组。跨度>

标签: javascript node.js dictionary higher-order-functions


【解决方案1】:

.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]

为了完全符合规范,您需要 also need 检查 this 是一个对象,callback 是可调用的,并检查 .call 与第二个回调如果有参数,则传递给myMap,但这些细节对于开始理解高阶函数并不重要。

【讨论】:

【解决方案2】:

我猜每个供应商都应该按照spec 实现它

实际的实现,例如 V8 可能有点复杂,参考this answer 开始。也可以参考github中的v8源码,但是单独看一部分可能不太容易理解。

引用上面的答案:

V8 开发人员在这里。我们有几种不同的实现技术 对于“内置”:有些是用 C++ 编写的,有些是用 Torque 编写的,有些是用什么编写的 我们调用 CodeStubAssembler,还有几个直接在汇编中。在早些时候 V8 版本,有些是用 JavaScript 实现的。这些中的每一个 策略有其自身的优势(权衡代码复杂性, 可调试性、各种情况下的性能、二进制大小和 内存消耗);再加上总有历史原因 代码随着时间的推移而发展。

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;否则让 Tundefined
  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, kO»)。
      4. ReturnIfAbrupt(mappedValue).
      5. status 为 CreateDataPropertyOrThrow (A, Pk, mappedValue)。
      6. ReturnIfAbrupt(状态)。
    5. k 增加 1。
  11. 返回A

【讨论】:

  • 我很好奇,规范的 &lt;li&gt; list-style-types 在 Chrome 和 FF 中是不可复制的。您是手动输入数字,还是我缺少更好的方法?
  • @CertainPerformance 哈哈。从源代码复制 HTML,将 HTML 复制到 markdown 在线工具。
猜你喜欢
  • 1970-01-01
  • 2015-09-19
  • 2011-12-13
  • 1970-01-01
  • 2017-09-06
  • 2011-06-15
  • 1970-01-01
  • 1970-01-01
  • 2023-03-21
相关资源
最近更新 更多