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

Bil*_*han 17 javascript dictionary node.js higher-order-functions

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

假设我写了类似的东西

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

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

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

Cer*_*nce 23

.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]
Run Code Online (Sandbox Code Playgroud)

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

  • 这让我想起了[一些其他答案](https://stackoverflow.com/search?q=Array.prototype.myMap)… (8认同)

sab*_*ker 7

我想每个供应商都应该按照规范来实现它

实际实现,例如 V8 可能有点复杂,请参考这个答案开始。也可以参考github中的v8源码,但是单独看一部分可能不太好理解。

引自上面的回答:

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

ES2015 规范:

  1. O成为 ToObject(这个值)。
  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. kPresentHasProperty ( O , Pk )。
    3. ReturnIfAbrupt( kPresent )。
    4. 如果kPresenttrue,则
      1. kValue为 Get( O , Pk )。
      2. ReturnIfAbrupt( kValue )。
      3. 映射值是调用(回调函数T,« kValue , k , O »)。
      4. ReturnIfAbrupt( mappedValue )。
      5. status为 CreateDataPropertyOrThrow ( A , Pk , mapsValue )。
      6. ReturnIfAbrupt(状态)。
    5. k增加1。
  11. 返回A

  • @CertainPerformance 哈哈。从源代码复制 HTML,HTML 到 Markdown 在线工具。 (5认同)
  • 我很好奇,规范的“&lt;li&gt;”“list-style-type”在 Chrome 和 FF 中都不可复制。你是手动写下数字的,还是我缺少更好的方法? (2认同)