Lodash源码阅读-arrayEach

79 阅读3分钟

Lodash 源码阅读-arrayEach

概述

arrayEach 是 Lodash 中的一个内部工具函数,专门用于数组迭代。它是 forEach/each 方法针对数组类型优化的特化版本,不支持迭代简写形式。它采用正向遍历策略,当迭代器函数返回 false 时会中断迭代过程,并始终返回原始数组引用。

前置学习

依赖函数

此函数没有直接依赖其他函数。

技术知识

  • JavaScript 数组遍历机制
  • 条件中断控制流
  • 短路返回技术
  • 函数回调机制
  • null/undefined 的安全处理

源码实现

/**
 * A specialized version of `_.forEach` for arrays without support for
 * iteratee shorthands.
 *
 * @private
 * @param {Array} [array] The array to iterate over.
 * @param {Function} iteratee The function invoked per iteration.
 * @returns {Array} Returns `array`.
 */
function arrayEach(array, iteratee) {
  var index = -1,
    length = array == null ? 0 : array.length;

  while (++index < length) {
    if (iteratee(array[index], index, array) === false) {
      break;
    }
  }
  return array;
}

实现思路

  • 设计为数组专用的迭代函数,与通用集合迭代相比具有更高效率
  • 实现前检查数组是否为 null/undefined,确保安全执行
  • 使用 while 循环而非 for 循环,减少变量声明和条件判断的开销
  • 支持在迭代过程中通过返回 false 来提前终止迭代
  • 保持函数式编程风格,始终返回原始数组以支持链式调用

源码解析

1. 函数定义与参数设计

function arrayEach(array, iteratee) {
  var index = -1,
    length = array == null ? 0 : array.length;
  // ...
}

arrayEach 接收两个参数:要迭代的数组 array 和每次迭代调用的函数 iteratee。初始迭代索引设置为 -1,这是因为循环开始时会先进行 ++index 操作,使第一次迭代从索引 0 开始。函数使用 array == null 简洁地同时检查 null 和 undefined 值,并在这种情况下将长度设置为 0,避免了在空值上迭代的错误。

2. 迭代实现与中断机制

while (++index < length) {
  if (iteratee(array[index], index, array) === false) {
    break;
  }
}

使用 while 循环实现迭代,每次迭代前增加索引。在每次迭代中,调用 iteratee 函数并传入三个参数:当前元素值、当前索引和原始数组。这使回调函数能够访问到完整的上下文信息。

关键设计点是对迭代器返回值的检查 - 如果返回严格等于 false,则立即中断循环。这提供了一种优雅的方式来在特定条件下提前终止迭代,无需额外的控制结构。

示例:

// 找到第一个偶数并停止
arrayEach([1, 3, 4, 5, 6], function (num) {
  console.log(num);
  return num % 2 !== 0; // 遇到偶数时返回 false
});
// 只会输出: 1, 3, 4

3. 返回值设计

return array;

函数始终返回传入的原始数组引用,无论是否完成全部迭代。这种设计支持函数链式调用,符合函数式编程范式。即使数组为 null/undefined,也会原样返回,保持一致的接口行为。

示例:

var numbers = [1, 2, 3];
var result = arrayEach(numbers, function (num) {
  console.log(num);
});
console.log(result === numbers); // true

总结

  • 使用 array == null 代替 array === null || array === undefined 简化空值检查
  • 巧用前置自增 ++index 结合初始值 -1,实现简洁的循环控制
  • 通过返回 false 实现迭代提前终止的模式值得在自定义集合操作中借鉴
  • 返回原始引用而非新值的设计使函数可以无缝集成到链式调用中