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

相关推荐
爱喝白开水a2 小时前
前端AI自动化测试:brower-use调研让大模型帮你做网页交互与测试
前端·人工智能·大模型·prompt·交互·agent·rag
Never_Satisfied2 小时前
在JavaScript / HTML中,关于querySelectorAll方法
开发语言·javascript·html
董世昌412 小时前
深度解析ES6 Set与Map:相同点、核心差异及实战选型
前端·javascript·es6
WeiXiao_Hyy3 小时前
成为 Top 1% 的工程师
java·开发语言·javascript·经验分享·后端
吃杠碰小鸡3 小时前
高中数学-数列-导数证明
前端·数学·算法
kingwebo'sZone3 小时前
C#使用Aspose.Words把 word转成图片
前端·c#·word
xjt_09013 小时前
基于 Vue 3 构建企业级 Web Components 组件库
前端·javascript·vue.js
我是伪码农3 小时前
Vue 2.3
前端·javascript·vue.js
夜郎king4 小时前
HTML5 SVG 实现日出日落动画与实时天气可视化
前端·html5·svg 日出日落
辰风沐阳4 小时前
JavaScript 的宏任务和微任务
javascript