Lodash 源码阅读-cloneArrayBuffer
概述
cloneArrayBuffer
是 Lodash 库中的一个内部工具函数,主要用于创建 ArrayBuffer 对象的克隆。在处理二进制数据时,这个函数确保了对 ArrayBuffer 的深度复制,而不是简单的引用复制,这对于避免副作用和保持数据独立性至关重要。
前置学习
依赖函数
cloneArrayBuffer
是一个相对独立的函数,不依赖其他 Lodash 工具函数。
技术知识
- ArrayBuffer:表示通用的、固定长度的原始二进制数据缓冲区
- TypedArray:如 Uint8Array,是访问二进制数据缓冲区的视图
- 构造函数属性 :JavaScript 对象的
constructor
属性,指向创建该对象的构造函数 - 二进制数据操作:在 JavaScript 中处理二进制数据的方法
源码实现
javascript
/**
* Creates a clone of `arrayBuffer`.
*
* @private
* @param {ArrayBuffer} arrayBuffer The array buffer to clone.
* @returns {ArrayBuffer} Returns the cloned array buffer.
*/
function cloneArrayBuffer(arrayBuffer) {
var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
new Uint8Array(result).set(new Uint8Array(arrayBuffer));
return result;
}
实现思路
cloneArrayBuffer
函数的实现思路非常直接:
- 创建一个与源 ArrayBuffer 大小相同的新 ArrayBuffer 对象
- 使用 Uint8Array 创建两个视图:一个指向新创建的 ArrayBuffer,另一个指向源 ArrayBuffer
- 通过 Uint8Array 的
set
方法,将源数组的所有字节复制到新数组中 - 返回完成复制的新 ArrayBuffer 对象
这种实现方式确保了新创建的 ArrayBuffer 与原始对象完全相同但互相独立,任何对新对象的修改都不会影响到原始对象。
源码解析
函数签名
javascript
function cloneArrayBuffer(arrayBuffer) {
函数接收一个参数:
arrayBuffer
:要克隆的 ArrayBuffer 对象
创建新的 ArrayBuffer
javascript
var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
这行代码做了两件事:
- 通过
arrayBuffer.constructor
获取原始 ArrayBuffer 的构造函数(即 ArrayBuffer) - 使用这个构造函数创建一个新的 ArrayBuffer 实例,大小与原始对象相同(
arrayBuffer.byteLength
)
使用 constructor
属性而不是直接使用 ArrayBuffer
构造函数,是一种防御性编程方法,确保即使在未来 ArrayBuffer 被子类化的情况下代码仍能正确工作。
复制数据
javascript
new Uint8Array(result).set(new Uint8Array(arrayBuffer));
这行代码是函数的核心,它执行了实际的数据复制:
new Uint8Array(arrayBuffer)
创建一个视图,指向原始 ArrayBuffer 中的所有字节new Uint8Array(result)
创建一个视图,指向新创建的 ArrayBuffer.set()
方法复制一个数组的所有元素到另一个数组,这里是将原始 ArrayBuffer 中的所有字节复制到新的 ArrayBuffer 中
Uint8Array 是以 8 位无符号整数格式查看 ArrayBuffer 的一种视图,使用它可以逐字节地操作 ArrayBuffer。
返回结果
javascript
return result;
函数返回复制完成的新 ArrayBuffer 对象。
总结
cloneArrayBuffer
是 Lodash 中一个看似简单但非常实用的工具函数,它解决了 JavaScript 中二进制数据深度复制的问题。通过利用 TypedArray 的能力,它实现了对 ArrayBuffer 数据的高效复制。
这个函数的实现体现了几个关键的编程原则:
- 不可变性:函数不修改输入参数,而是返回一个新的对象
- 封装复杂性:将二进制数据复制的细节封装在简单的函数接口后面
- 组合复用:作为其他克隆函数的基础组件,遵循了"做好一件事"的设计原则
- 防御性编程 :使用
constructor
属性而不是直接引用构造函数,增强代码的鲁棒性
在处理二进制数据的 JavaScript 应用中,cloneArrayBuffer
提供了一种简洁可靠的方式来创建数据的深度副本,是二进制数据操作中不可或缺的工具。