简洁再简洁的JavaScript浅拷贝和深拷贝

52 阅读2分钟

浅拷贝

浅拷贝复制对象或数据的一层的内容,不会复制嵌套对象或数组的内容,只复制原始数据结构的引用,不会创建原始数据结构的副本。

浅拷贝的方法

  1. 对象展开运算符 (...)
const obj = {a:1,b:2,c:3}
const newObj = {...obj}

注意:这种方法只能用于对象的浅拷贝,如果对象中嵌套了其他对象,它们仍然是引用关系

2.Object.assign() 方法:

将一个或多个源对象的属性复制到目标对象,从而实现浅拷贝:

const obj = {a:1,b:2,c:3}
const newObj = Object.assgin({}, obj)

同理,也是只能处理第一层属性

3.数组扩展运算符 (...)

const arr = [1,2,3]
const newArr = [...arr]

适用于数组,类似对象展开运算符

4.Array.slice()仅限数组

const arr = [1,2,3]
const newArr = arr.slice()

5.Array.concat()仅限数组

const arr = [1,2,3]
const newArr = arr.concat()

深拷贝

深拷贝恰恰相反,递归地复制所有嵌套的对象和数组,不共享原始数据结构的引用,创建原始数据结构的副本,深拷贝后的对象或数组的修改不会影响原始数据结构。

  1. 最熟悉JSON.parse(JSON.stringify())
const obj = {a:1,b:{c:2}}
const deepCopy = JSON.parse(JSON.stringify(obj))

缺点是不能处理包含函数、undefined 等特殊值的对象

2.递归函数来遍历对象的每一层,并复制其属性

function deepCopy(obj) {
  if (obj === null || typeof obj !== 'object') {
    return obj;
  }
  const copy = Array.isArray(obj) ? [] : {};
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      copy[key] = deepCopy(obj[key]);
    }
  }
  return copy;
}
const originalObject = { a: 1, b: { c: 2 } };
const newObj = deepCopy(originalObject);

可以处理包含函数等特殊值的对象,但可能存在循环引用的问题,需要额外的处理来解决。

3.第三方库

import _ from 'lodash'

const obj = { a: 1, b: { c: 2 } };
const deepCopy = _.cloneDeep(obj);

稳健且高效的深拷贝实现