.map()之类的高阶函数如何在JavaScript内部进行工作?


17

如今,每个人都试图使用这类高阶函数以更少的代码获得有希望的结果。但是我不知道这些功能在内部如何工作。

假设我写类似

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

我知道'number'数组的每个元素都在一个一个地迭代,但是怎么做呢?

我试图进行搜索,但没有得到满意的答复。


10
看看Array.map的polyfil
AZ_

这是一个名为mapArray 的函数。该函数将函数作为参数,然后在遍历数组时调用该函数。然后,函数调用的返回值以数组形式返回。
ssc-hrep3

map基本上像foreach一样工作,用于迭代数组,这意味着它将一一获取数组的所有元素,然后对每个元素应用给定的命令/操作,然后将其推入新数组。
Adnan Tariq

Answers:


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]

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


8
这让我想起了其他答案 ……
Bergi

7

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

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

引用以上答案:

V8开发人员在这里。我们为“ buildins”提供了几种不同的实现技术:有些是用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;否则让T成为不确定
  7. A为ArraySpeciesCreate(O len)。
  8. ReturnIfAbrupt( A)。
  9. k为0。
  10. 重复,而k < len
    1. Pk为ToString( k)。
    2. kPresentHasPropertyO Pk)。
    3. ReturnIfAbrupt( kPresent)。
    4. 如果kPresent true,则
      1. kValue为Get(OPk)。
      2. ReturnIfAbrupt(kValue)。
      3. mapedValue为Call(callbackfnT,« kValuekO »)。
      4. ReturnIfAbrupt( mappingValue)。
      5. 假设status为CreateDataPropertyOrThrow(APk mappingValue)。
      6. ReturnIfAbrupt(状态)。
    5. 增加k 1。
  11. 返回一个

2
我很好奇,该规范<li> list-style-type不能在Chrome和FF中复制。您是手动输入数字,还是缺少更好的方法?
SomePerformance

5
@CertainPerformance大声笑。从源代码复制HTML,将HTML复制到markdown在线工具。
sabithpocker
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.