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 实现迭代提前终止的模式值得在自定义集合操作中借鉴
- 返回原始引用而非新值的设计使函数可以无缝集成到链式调用中