lodash 的 cloneBuffer 函数关于 Buffer 深拷贝的疑惑

先张贴下源码

function cloneBuffer(buffer, isDeep) {
  if (isDeep) {
    return buffer.slice()
  }
  const length = buffer.length
  const result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length)

  buffer.copy(result)
  return result
}

在源码中,当 isDeeptrue,即要深拷贝时,使用的是 buffer.slice 方法。

但是关于 slice 方法,文档有如下描述:

Returns a new Buffer that references the same memory as the original

链接:https://nodejs.org/docs/latest-v13.x/api/buffer.html#buffer_buf_slice_start_end

也即 slice 所返回的新 Buffer 和原 Buffer 指向的是同一块内存。

在和 TypedArray.slice 的对比中更有如下描述:

While TypedArray#slice() creates a copy of part of the TypedArray, Buffer#slice() creates a view over the existing Buffer without copying.

链接:https://nodejs.org/docs/lates...

清楚说明了 slicewithout copying 的,为什么 lodash会用作深拷贝呢?

阅读 4.5k
2 个回答

slice() 可以对数组的第一层级进行深拷贝, 第一层级数据类型只限基本数据类型。

引用 MDN 的说法:

arr.slice([begin[, end]])

slice() 方法返回一个新的数组对象,这一对象是一个由 beginend决定的原数组的浅拷贝(包括begin,不包括end)。原始数组不会被改变。

假如你 slice 的数组数据是基本类型,可以当成深拷贝来用。例如

a = [1, 2, 3, 4]
b = a.slice()
b.push(5)
console.log(a) // 1,2,3,4
console.log(b) // 1,2,3,4,5

但如果 slice 的数组数据是引用类型,就不行。

a = [{ test: 1 }]
b = a.slice()
b[0].test = 2
console.log(a[0].test) // 2
console.log(b[0].test) // 2
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题