Lodash源码阅读-cloneDataView

Lodash 源码阅读-cloneDataView

概述

cloneDataView 是 Lodash 库中的一个内部工具函数,主要用于创建 DataView 对象的克隆。DataView 提供了对二进制数据缓冲区的低级读写接口,这个函数确保了在克隆复杂对象时能够正确处理 DataView 类型,支持浅拷贝和深拷贝两种模式。

前置学习

依赖函数

  • cloneArrayBuffer:用于克隆 DataView 底层的 ArrayBuffer 对象,实现深拷贝时使用

技术知识

  • DataView:JavaScript 中用于读写二进制数据缓冲区的底层接口
  • ArrayBuffer:表示通用的、固定长度的原始二进制数据缓冲区
  • 构造函数属性 :JavaScript 对象的 constructor 属性,指向创建该对象的构造函数
  • 浅拷贝与深拷贝:对象复制的两种模式及其区别

源码实现

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

实现思路

cloneDataView 函数的实现思路直接明了:

  1. 根据 isDeep 参数决定是否对 DataView 的底层 ArrayBuffer 进行深拷贝:
    • 如果是深拷贝(isDeep 为 true),则使用 cloneArrayBuffer 函数复制底层的 ArrayBuffer
    • 如果是浅拷贝(isDeep 为 false),则直接使用原始 DataView 的 buffer 引用
  2. 使用 DataView 的构造函数,结合提供的 buffer(原始或克隆的)和偏移量信息,创建一个新的 DataView 对象
  3. 返回新创建的 DataView 对象

这种实现方式灵活地支持了浅拷贝和深拷贝两种需求,使得函数可以在不同的克隆场景中使用。

源码解析

函数签名

javascript 复制代码
function cloneDataView(dataView, isDeep) {

函数接收两个参数:

  • dataView:要克隆的 DataView 对象
  • isDeep:可选的布尔值,指定是否进行深拷贝

处理 buffer

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

这行代码根据 isDeep 参数决定如何处理 DataView 的底层 ArrayBuffer:

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

深拷贝确保了新创建的 DataView 有自己独立的底层 ArrayBuffer,任何对新 DataView 的修改都不会影响原始对象。而浅拷贝则保持了对同一底层 ArrayBuffer 的引用,修改会相互影响。

创建新的 DataView

javascript 复制代码
return new dataView.constructor(
  buffer,
  dataView.byteOffset,
  dataView.byteLength
);

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

  1. 使用 dataView.constructor(即 DataView 构造函数)创建一个新的 DataView 实例
  2. 传递三个参数:
    • buffer:上一步获取或创建的 ArrayBuffer
    • dataView.byteOffset:原始 DataView 的字节偏移量
    • dataView.byteLength:原始 DataView 的字节长度

使用 constructor 属性而不是直接使用 DataView 构造函数,是一种防御性编程方法,确保代码在各种环境中的兼容性。

浅拷贝与深拷贝的区别

cloneDataView 函数中,浅拷贝和深拷贝的区别在于对底层 ArrayBuffer 的处理:

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

// 深拷贝 - 创建底层 ArrayBuffer 的独立副本
var deepClone = cloneDataView(originalDataView, true);
  • 浅拷贝:新旧 DataView 指向同一个 ArrayBuffer,一个 DataView 的修改会影响另一个
  • 深拷贝:新的 DataView 指向一个独立的 ArrayBuffer 副本,相互之间的修改不会影响对方

总结

cloneDataView 是 Lodash 中一个专门用于克隆 DataView 对象的工具函数,它巧妙地利用了 cloneArrayBuffer 来支持深拷贝,同时也提供了浅拷贝的选项。

这个函数的实现体现了几个重要的编程原则:

  1. 单一职责:函数只负责一件事情 - 克隆 DataView 对象
  2. 开闭原则 :通过参数化 isDeep 实现了功能的扩展,而不需要修改函数内部实现
  3. 组合复用 :利用 cloneArrayBuffer 函数处理底层 ArrayBuffer 的复制,体现了"组合优于继承"的思想
  4. 防御性编程 :使用 constructor 属性而不是直接引用构造函数,增强了代码的兼容性

在处理二进制数据的应用中,cloneDataView 提供了一种灵活而可靠的方式来创建 DataView 的副本,无论是需要共享底层数据还是完全独立的数据副本。

相关推荐
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++·算法