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 的实现方式仍然有其价值,特别是在需要精确控制复制过程或复制到现有数组时。

相关推荐
qq. 28040339843 小时前
CSS层叠顺序
前端·css
喝拿铁写前端3 小时前
SmartField AI:让每个字段都找到归属!
前端·算法
猫猫不是喵喵.3 小时前
vue 路由
前端·javascript·vue.js
烛阴3 小时前
JavaScript Import/Export:告别混乱,拥抱模块化!
前端·javascript
bin91534 小时前
DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之添加行拖拽排序功能示例12,TableView16_12 拖拽动画示例
前端·javascript·vue.js·ecmascript·deepseek
GISer_Jing4 小时前
[Html]overflow: auto 失效原因,flex 1却未设置min-height &overflow的几个属性以及应用场景
前端·html
程序员黄同学4 小时前
解释 Webpack 中的模块打包机制,如何配置 Webpack 进行项目构建?
前端·webpack·node.js
拉不动的猪4 小时前
vue自定义“权限控制”指令
前端·javascript·vue.js
再学一点就睡4 小时前
浏览器页面渲染机制深度解析:从构建 DOM 到 transform 高效渲染的底层逻辑
前端·css
拉不动的猪5 小时前
刷刷题48 (setState常规问答)
前端·react.js·面试