对象数组的拷贝

133 阅读1分钟

浅拷贝

浅拷贝是指对对象和数组等引用数据类型内存地址的拷贝,拷贝后的值和之前的值指向内存中的同一个地址。修改其中一个值,另一个值也会随之改变。 === 比较返回true

const obj = {a:1};
const obj2 = obj;

obj2.a = 2;
console.log(obj); // {a:2}
console.log(obj2); // {a:2}
console.log(obj===obj2); //true

深拷贝

在内存中开辟一块新的空间用来存储新的值,新的值和旧的值不会相互影响。 === 比较返回false

  1. 单层深拷贝 使用Object.assign 复制一个对象
const obj = { a: 1, b: { c: 1 } };
const obj2 = Object.assign({}, obj);

console.log(obj === obj2); //false

obj2.a = 2;
obj2.b.c = 2;
console.log("obj", obj); // { a: 1, b: { c: 2 } }
console.log("obj2", obj2); // { a: 2, b: { c: 2 } }
console.log(obj.b === obj2.b); //true

使用展开运算符创建一个新的对象或数组

const obj = { a: 1, b: { c: 1 } };
const obj3 = { ...obj };

console.log(obj === obj3); // false

obj3.a = 3;
obj3.b.c = 3;
console.log("obj", obj); // { a: 1, b: { c: 3 } }
console.log("obj3", obj3); // { a: 2, b: { c: 3 } }
console.log(obj.b === obj3.b); // true
  1. 使用JSON.stringify 进行深拷贝。 可以实现数组和对象的深拷贝,但是不能拷贝正则和函数
const obj = { a: 1, b: { c: 1 } };

const obj2 = obj;
const obj3 = JSON.parse(JSON.stringify(obj));

obj2.b.c = 2;
obj3.b.c = 3;

console.log(obj); // { a: 1, b: { c: 2 } }
console.log(obj2); // { a: 1, b: { c: 2 } }
console.log(obj3); // { a: 1, b: { c: 3 } }

console.log(obj === obj2); //true
console.log(obj === obj3); //fasle
  1. 手写一个适用大多数数据类型的递归深拷贝
const cloneDeep = (param) => {
  if (param === null || typeof param !== "object") return param;

  if (Array.isArray(param)) param.map((item) => cloneDeep(item));

  if (obj instanceof Date) return new Date(param);

  if (obj instanceof RegExp) return new RegExp(param);

  if (getType(param) === "object") {
    const obj = {};
    Object.keys(param).forEach((key) => {
      obj[key] = cloneDeep(param[key]);
    });
    return obj;
  }
};
  1. 使用工具库进行深拷贝
import { cloneDeep } from 'lodash';

const obj = {a:1}

const cloneObj = cloneDeep(obj)