Lodash源码阅读-copyArray

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 函数的实现思路非常直观:

  1. 接收两个参数:源数组 source 和目标数组 array(可选)
  2. 如果没有提供目标数组,则创建一个与源数组长度相同的新数组
  3. 使用循环遍历源数组的每个元素,将其复制到目标数组的相应位置
  4. 返回目标数组

源码解析

参数处理

javascript 复制代码
var index = -1,
  length = source.length;

array || (array = Array(length));

这段代码首先定义了两个变量:

  • index:初始化为 -1,用于跟踪当前处理的数组索引
  • length:源数组的长度

然后检查是否提供了目标数组 array

  • 如果 array 为假值(如 undefinednull),则创建一个新数组
  • 新数组的长度与源数组相同,使用 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 函数虽然简单,但它体现了几个重要的编程原则:

  1. 单一职责原则

    • 函数只做一件事:复制数组元素
    • 实现简单明了,易于理解和维护
  2. 灵活性

    • 支持复制到新数组或现有数组
    • 通过参数控制行为,而不是硬编码
  3. 性能考虑

    • 预分配数组大小,避免动态增长带来的性能开销
    • 使用基本的循环而不是高阶函数,在某些情况下可能更高效
  4. 代码复用

    • 作为基础工具函数,被多个高级函数使用
    • 避免在多个地方重复实现相同的逻辑

虽然现代 JavaScript 提供了多种数组复制方法(如 Array.prototype.slice()[...array] 展开语法、Array.from(array) 等),但 copyArray 的实现方式仍然有其价值,特别是在需要精确控制复制过程或复制到现有数组时。

相关推荐
百万蹄蹄向前冲1 小时前
Trae分析Phaser.js游戏《洋葱头捡星星》
前端·游戏开发·trae
朝阳5812 小时前
在浏览器端使用 xml2js 遇到的报错及解决方法
前端
GIS之路2 小时前
GeoTools 读取影像元数据
前端
ssshooter3 小时前
VSCode 自带的 TS 版本可能跟项目TS 版本不一样
前端·面试·typescript
你的人类朋友3 小时前
【Node.js】什么是Node.js
javascript·后端·node.js
Jerry3 小时前
Jetpack Compose 中的状态
前端
dae bal4 小时前
关于RSA和AES加密
前端·vue.js
柳杉4 小时前
使用three.js搭建3d隧道监测-2
前端·javascript·数据可视化
lynn8570_blog4 小时前
低端设备加载webp ANR
前端·算法
LKAI.5 小时前
传统方式部署(RuoYi-Cloud)微服务
java·linux·前端·后端·微服务·node.js·ruoyi