Lodash源码阅读-cloneTypedArray

Lodash 源码阅读-cloneTypedArray

概述

cloneTypedArray 是 Lodash 库中的一个内部工具函数,主要用于创建 TypedArray(类型化数组)对象的克隆。TypedArray 是处理二进制数据的专用数组类型,如 Int8Array、Uint8Array、Float32Array 等,这个函数在深度克隆操作中确保了对这类特殊数组的正确处理,支持浅拷贝和深拷贝两种模式。

前置学习

依赖函数

  • cloneArrayBuffer:用于克隆 TypedArray 底层的 ArrayBuffer 对象,在深拷贝模式下使用

技术知识

  • TypedArray:JavaScript 中的类型化数组,包括 Int8Array、Uint8Array、Float32Array 等多种类型
  • ArrayBuffer:类型化数组底层的二进制数据缓冲区
  • 构造函数属性 :JavaScript 对象的 constructor 属性,指向创建该对象的构造函数
  • 浅拷贝与深拷贝:对象复制的两种模式及其在处理引用类型时的区别

源码实现

javascript 复制代码
/**
 * Creates a clone of `typedArray`.
 *
 * @private
 * @param {Object} typedArray The typed array to clone.
 * @param {boolean} [isDeep] Specify a deep clone.
 * @returns {Object} Returns the cloned typed array.
 */
function cloneTypedArray(typedArray, isDeep) {
  var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
  return new typedArray.constructor(
    buffer,
    typedArray.byteOffset,
    typedArray.length
  );
}

实现思路

cloneTypedArray 函数的实现思路清晰直接:

  1. 根据 isDeep 参数决定如何处理 TypedArray 的底层 ArrayBuffer:
    • 如果是深拷贝(isDeep 为 true),则使用 cloneArrayBuffer 函数创建底层 ArrayBuffer 的独立副本
    • 如果是浅拷贝(isDeep 为 false 或未提供),则直接使用原始 TypedArray 的 buffer 引用
  2. 使用原始 TypedArray 的构造函数创建一个新的 TypedArray 实例,传入处理后的 buffer、原始的字节偏移量和长度
  3. 返回新创建的 TypedArray 对象

这种实现方式既可以创建共享底层数据的浅拷贝,也可以创建完全独立的深拷贝,满足不同场景的需求。

源码解析

函数签名

javascript 复制代码
function cloneTypedArray(typedArray, isDeep) {

函数接收两个参数:

  • typedArray:要克隆的类型化数组对象(如 Int8Array、Uint8Array 等)
  • isDeep:可选的布尔值,指定是否进行深拷贝

处理 buffer

javascript 复制代码
var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;

这行代码是函数的核心,它根据 isDeep 参数决定如何处理底层的 ArrayBuffer:

  • 如果 isDeep 为 true,调用 cloneArrayBuffer 函数创建 typedArray.buffer 的深拷贝
  • 如果 isDeep 为 false 或未提供,直接使用原始的 typedArray.buffer 引用

在深拷贝模式下,新创建的 TypedArray 将拥有自己独立的底层数据存储,不会与原始数组共享数据。而在浅拷贝模式下,新旧数组共享同一个底层 ArrayBuffer,对一个数组的修改会影响另一个。

创建新的 TypedArray

javascript 复制代码
return new typedArray.constructor(
  buffer,
  typedArray.byteOffset,
  typedArray.length
);

这行代码创建并返回一个新的 TypedArray 对象:

  1. 通过 typedArray.constructor 获取原始类型化数组的构造函数(如 Int8Array、Float32Array 等)
  2. 使用该构造函数创建一个新的类型化数组实例,传入三个参数:
    • buffer:上一步获取或创建的 ArrayBuffer
    • typedArray.byteOffset:原始类型化数组的字节偏移量
    • typedArray.length:原始类型化数组的长度(元素个数)

使用 constructor 属性而不是硬编码特定的构造函数,使得这个函数可以处理所有类型的 TypedArray,保持了代码的通用性和扩展性。

不同类型的 TypedArray

JavaScript 提供了多种类型化数组,cloneTypedArray 可以处理所有这些类型:

  • Int8Array:8 位有符号整数数组
  • Uint8Array:8 位无符号整数数组
  • Uint8ClampedArray:8 位无符号整数数组(固定范围)
  • Int16Array:16 位有符号整数数组
  • Uint16Array:16 位无符号整数数组
  • Int32Array:32 位有符号整数数组
  • Uint32Array:32 位无符号整数数组
  • Float32Array:32 位浮点数数组
  • Float64Array:64 位浮点数数组

无论哪种类型,cloneTypedArray 都能通过 constructor 属性正确地创建对应类型的克隆。

浅拷贝与深拷贝的区别

javascript 复制代码
// 浅拷贝 - 共享同一个底层 ArrayBuffer
var shallowClone = cloneTypedArray(originalArray, false);

// 深拷贝 - 创建底层 ArrayBuffer 的独立副本
var deepClone = cloneTypedArray(originalArray, true);

// 修改测试
shallowClone[0] = 99; // 也会修改 originalArray[0]
deepClone[0] = 99; // 不会影响 originalArray[0]

浅拷贝和深拷贝的关键区别在于对底层 ArrayBuffer 的处理:

  • 浅拷贝创建的新数组与原始数组共享同一个底层 ArrayBuffer,任何一方的修改都会影响另一方
  • 深拷贝通过复制底层 ArrayBuffer 创建完全独立的新数组,两个数组之间的修改互不影响

总结

cloneTypedArray 是 Lodash 中一个专门用于克隆类型化数组的工具函数,它通过灵活处理底层 ArrayBuffer,实现了对各种类型化数组的浅拷贝和深拷贝。

这个函数的实现体现了几个重要的软件设计原则:

  1. 通用性 :使用 constructor 属性使函数能够处理所有类型的 TypedArray
  2. 灵活性 :通过 isDeep 参数支持浅拷贝和深拷贝两种模式
  3. 组合复用 :利用 cloneArrayBuffer 函数处理底层数据的复制,避免代码重复
  4. 单一职责:函数只关注于类型化数组的克隆,遵循"做好一件事"的原则

在处理二进制数据和数值计算的 JavaScript 应用中,cloneTypedArray 提供了一种简洁而强大的方式来创建类型化数组的副本,为数据处理提供了更多的灵活性和安全性。

相关推荐
zhougl9961 小时前
html处理Base文件流
linux·前端·html
花花鱼1 小时前
node-modules-inspector 可视化node_modules
前端·javascript·vue.js
HBR666_1 小时前
marked库(高效将 Markdown 转换为 HTML 的利器)
前端·markdown
careybobo3 小时前
海康摄像头通过Web插件进行预览播放和控制
前端
TDengine (老段)3 小时前
TDengine 中的关联查询
大数据·javascript·网络·物联网·时序数据库·tdengine·iotdb
杉之4 小时前
常见前端GET请求以及对应的Spring后端接收接口写法
java·前端·后端·spring·vue
喝拿铁写前端4 小时前
字段聚类,到底有什么用?——从系统混乱到结构认知的第一步
前端
再学一点就睡4 小时前
大文件上传之切片上传以及开发全流程之前端篇
前端·javascript
木木黄木木5 小时前
html5炫酷图片悬停效果实现详解
前端·html·html5
请来次降维打击!!!6 小时前
优选算法系列(5.位运算)
java·前端·c++·算法