Lodash 源码阅读-copyArray
概述
copyArray
是 Lodash 中的一个内部工具函数,用于复制数组的所有元素到一个新数组或指定的目标数组中。它实现了数组的浅拷贝(shallow copy),即只复制数组元素的引用,而不是深度复制数组元素的内容。
前置学习
依赖函数
copyArray
是一个相对独立的基础函数,不依赖其他 Lodash 函数。
源码实现
javascript
/**
* Copies the values of `source` to `array`.
*
* @private
* @param {Array} source The array to copy values from.
* @param {Array} [array=[]] The array to copy values to.
* @returns {Array} Returns `array`.
*/
function copyArray(source, array) {
var index = -1,
length = source.length;
array || (array = Array(length));
while (++index < length) {
array[index] = source[index];
}
return array;
}
实现思路
copyArray
函数的实现思路非常直观:
- 接收两个参数:源数组
source
和目标数组array
(可选) - 如果没有提供目标数组,则创建一个与源数组长度相同的新数组
- 使用循环遍历源数组的每个元素,将其复制到目标数组的相应位置
- 返回目标数组
源码解析
参数处理
javascript
var index = -1,
length = source.length;
array || (array = Array(length));
这段代码首先定义了两个变量:
index
:初始化为 -1,用于跟踪当前处理的数组索引length
:源数组的长度
然后检查是否提供了目标数组 array
:
- 如果
array
为假值(如undefined
或null
),则创建一个新数组 - 新数组的长度与源数组相同,使用
Array(length)
预分配空间
这里使用了 JavaScript 的短路逻辑运算符 ||
,如果 array
为假值,则执行右侧的表达式。这是一种常见的设置默认值的简洁方式。
数组复制
javascript
while (++index < length) {
array[index] = source[index];
}
这是函数的核心逻辑,使用 while
循环遍历源数组的每个元素:
- 循环从索引 0 开始(因为
index
初始值为 -1,第一次++index
后变为 0) - 循环继续,直到处理完源数组中的所有元素(
index < length
不再成立) - 每次迭代,将源数组的当前元素
source[index]
复制到目标数组的相应位置array[index]
这种手动复制的方式比使用 Array.prototype.slice()
或展开运算符 [...source]
更直接,在某些情况下可能更高效,特别是当需要复制到现有数组而不是创建新数组时。
返回结果
javascript
return array;
函数最后返回目标数组,无论是新创建的还是传入的。这使得函数可以链式调用,也符合 Lodash 的一般设计风格。
总结
copyArray
函数虽然简单,但它体现了几个重要的编程原则:
-
单一职责原则:
- 函数只做一件事:复制数组元素
- 实现简单明了,易于理解和维护
-
灵活性:
- 支持复制到新数组或现有数组
- 通过参数控制行为,而不是硬编码
-
性能考虑:
- 预分配数组大小,避免动态增长带来的性能开销
- 使用基本的循环而不是高阶函数,在某些情况下可能更高效
-
代码复用:
- 作为基础工具函数,被多个高级函数使用
- 避免在多个地方重复实现相同的逻辑
虽然现代 JavaScript 提供了多种数组复制方法(如 Array.prototype.slice()
、[...array]
展开语法、Array.from(array)
等),但 copyArray
的实现方式仍然有其价值,特别是在需要精确控制复制过程或复制到现有数组时。