返回

ES6 API 原理剖析:一探 forEach 的内部运作

前端

在 JavaScript 的世界里,`` 是一个必不可少的工具,它允许我们遍历数组并对每个元素执行特定的操作。而在 ES6 中,forEach 的实现原理又有了怎样的新变化呢?让我们深入剖析一番,揭开其神秘面纱。

forEach 的前世今生

ES6 之前的 forEach 实现可以追溯到 ECMAScript 5,它本质上是一个高阶函数,接受一个回调函数作为参数,对数组中的每个元素依次调用该回调函数。

Array.prototype.forEach = function(callbackFn, thisArg) {
  for (var i = 0; i < this.length; i++) {
    callbackFn.call(thisArg, this[i], i, this);
  }
};

ES6 中的优化

ES6 对 forEach 的实现进行了优化,采用了更简洁高效的方式:

Array.prototype.forEach = function(callbackFn, thisArg) {
  var _this;
  if (type(thisArg) === 'undefined') _this = this;
  else _this = thisArg;
  return typedForEach(_this, callbackFn);
};

在这个改进的版本中,typedForEach 作为一个内部函数被调用。它接受数组和回调函数作为参数,执行遍历操作:

function typedForEach(arr, fn) {
  if (isArrayLike(arr)) {
    for (var i = 0, len = arr.length; i < len; i++) {
      fn(arr[i], i, arr);
    }
  } else {
    for (var key in arr) {
      if (hasOwnProperty.call(arr, key)) {
        fn(arr[key], key, arr);
      }
    }
  }
}

优化亮点

ES6 中 forEach 的优化主要体现在以下几个方面:

  • 执行速度提升: typedForEach 函数直接遍历数组或对象,避免了在每一次迭代中检查 thisArg 的类型,提升了执行效率。
  • thisArg 处理优化: 如果未指定 thisArg,则直接使用数组本身作为 this 上下文,避免了不必要的对象创建。
  • 遍历算法优化: 对于类数组对象(如 arguments)和对象,forEach 使用了不同的遍历算法,分别针对数组和对象进行了优化。