Lodash源码阅读-cloneBuffer

Lodash 源码阅读-cloneBuffer

概述

cloneBuffer 是 Lodash 内部用于克隆 Node.js Buffer 对象的函数。Buffer 是 Node.js 中用于处理二进制数据的类,该函数可以创建一个与原 Buffer 对象内容相同但内存地址不同的新 Buffer 对象,支持浅克隆和深克隆。

前置学习

依赖函数

  • 无直接依赖其他函数

相关技术知识

  • Node.js Buffer 对象
  • Buffer.allocUnsafe 方法
  • Buffer.slice 方法
  • Buffer.copy 方法
  • JavaScript 条件判断和对象构造

源码实现

js 复制代码
/**
 * Creates a clone of  `buffer`.
 *
 * @private
 * @param {Buffer} buffer The buffer to clone.
 * @param {boolean} [isDeep] Specify a deep clone.
 * @returns {Buffer} Returns the cloned buffer.
 */
function cloneBuffer(buffer, isDeep) {
  if (isDeep) {
    return buffer.slice();
  }
  var length = buffer.length,
    result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);

  buffer.copy(result);
  return result;
}

实现思路

cloneBuffer 函数的实现思路如下:

  1. 通过参数 isDeep 来决定是进行深克隆还是浅克隆
  2. 如果是深克隆(isDeeptrue),直接调用 Buffer 的 slice() 方法创建一个全新的 Buffer 副本
  3. 如果是浅克隆:
    • 首先获取原 Buffer 的长度
    • 然后通过 allocUnsafe(如果可用)或通过构造函数创建一个相同长度的新 Buffer 对象
    • 使用 copy 方法将原 Buffer 的内容复制到新 Buffer 中
  4. 返回克隆后的新 Buffer 对象

源码解析

深克隆处理

js 复制代码
if (isDeep) {
  return buffer.slice();
}

isDeeptrue 时,函数直接调用 Buffer 对象的 slice() 方法创建一个新的 Buffer 对象。在 Node.js 中,Buffer.slice() 会返回一个新的 Buffer 对象,它包含原 Buffer 的一个副本,而不是引用同一内存区域,因此是一种深克隆方式。

示例:

js 复制代码
const buf1 = Buffer.from("hello");
const buf2 = buf1.slice();

console.log(buf1); // <Buffer 68 65 6c 6c 6f>
console.log(buf2); // <Buffer 68 65 6c 6c 6f>
console.log(buf1 === buf2); // false

// 修改 buf2 不会影响 buf1
buf2[0] = 0x48;
console.log(buf1.toString()); // 'hello' - 未改变
console.log(buf2.toString()); // 'Hello' - 已改变

浅克隆处理

js 复制代码
var length = buffer.length,
  result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);

buffer.copy(result);

当进行浅克隆时,函数会:

  1. 获取原 Buffer 的长度
  2. 创建一个新的 Buffer:
    • 优先使用 allocUnsafe 方法(如果可用)
    • 如果 allocUnsafe 不可用,则使用原 Buffer 的构造函数创建
  3. 使用 buffer.copy() 方法将原 Buffer 的内容复制到新创建的 Buffer 中

这里的 allocUnsafe 是一个从 Node.js 环境中获取的 Buffer 方法引用:

js 复制代码
var Buffer = moduleExports ? context.Buffer : undefined,
    // ...其他代码
    allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined,

Buffer.allocUnsafe() 是 Node.js 中创建 Buffer 的一种高效方法,它分配内存但不会初始化内存内容,因此比 Buffer.alloc() 更快,但需要手动填充缓冲区以避免潜在的安全风险。

示例:

js 复制代码
const buf1 = Buffer.from("hello");
const buf2 = Buffer.allocUnsafe(buf1.length);
buf1.copy(buf2);

console.log(buf1.toString()); // 'hello'
console.log(buf2.toString()); // 'hello'
console.log(buf1 === buf2); // false

应用场景

在 Lodash 内部的应用

cloneBuffer 主要在 Lodash 的 baseClone 函数中使用,该函数是 clonecloneDeep 方法的核心实现。当需要克隆 Buffer 类型的值时,会使用该函数:

js 复制代码
// 在 baseClone 函数中
if (isBuffer(value)) {
  return cloneBuffer(value, isDeep);
}

总结

  1. 效率优先 :优先使用 allocUnsafe 方法提高性能,同时兼顾了不同环境下的兼容性
  2. 灵活性 :通过 isDeep 参数支持深克隆和浅克隆两种模式
  3. 依赖隔离 :检测 allocUnsafe 是否可用,确保在非 Node.js 环境中也能正常工作

这种针对特定类型(Buffer)数据的专门处理方法,展示了 Lodash 库在处理各种 JavaScript 数据类型时的全面性和精确性,使得 Lodash 的克隆功能能够正确处理包括 Buffer 在内的各种复杂数据类型。

相关推荐
还是鼠鼠1 小时前
Node.js自定义中间件
javascript·vscode·中间件·node.js·json·express
大莲芒4 小时前
react 15-16-17-18各版本的核心区别、底层原理及演进逻辑的深度解析--react17
前端·react.js·前端框架
木木黄木木6 小时前
html5炫酷3D文字效果项目开发实践
前端·3d·html5
Li_Ning216 小时前
【接口重复请求】axios通过AbortController解决页面切换过快,接口重复请求问题
前端
胡八一7 小时前
Window调试 ios 的 Safari 浏览器
前端·ios·safari
Dontla7 小时前
前端页面鼠标移动监控(鼠标运动、鼠标监控)鼠标节流处理、throttle、限制触发频率(setTimeout、clearInterval)
前端·javascript
再学一点就睡7 小时前
深拷贝与浅拷贝:代码世界里的永恒与瞬间
前端·javascript
CrimsonHu7 小时前
B站首页的 Banner 这么好看,我用原生 JS + 三大框架统统给你复刻一遍!
前端·javascript·css
Enti7c7 小时前
前端表单输入框验证
前端·javascript·jquery
拉不动的猪8 小时前
几种比较实用的指令举例
前端·javascript·面试