JS面试题:如何实现一个深拷贝?

761 阅读1分钟

什么是浅拷贝: 复制后的对象会与原对象共用内存地址,会互相干扰

什么是深拷贝: 复制的对象会创建一个新的内存地址,原对象内存地址的属性会复制到新对象的内存地址,互不干扰

这是浅拷贝

let a = {
    age: 20
};

let b = a;

b.age = 30;

console.log(a.age); // 30

Obj.assign() 也是浅拷贝

Object.assign(b, a)   // 前面是新对象,后面是原对象

所以想要复制一个全新的对象时,就要进行深拷贝

实现深拷贝

1、利用JSON类

就是将一个对象转为JSON字符串,再转回JSON对象

let a = {
    age: 20
};

let b = JSON.parse(JSON.stringify(a));

b.age = 30;

console.log(a.age); // 20

  • 优点:方便快捷,性能相对比较好

  • 缺点:复杂的对象进行JSON转换有可能会丢失属性,如下代码

let a = {
    age: 20,
    local: function() {
        return 5;
    }
};

let b = JSON.parse(JSON.stringify(a));

console.log(b); // { age : 20 }
console.log(b.local()); //  b.loacl is not a function

2、手写实现深拷贝函数(适用于复杂对象)

// 深拷贝的实现
function deepCopy(object) {
  if (!object || typeof object !== "object") return;

  let newObject = Array.isArray(object) ? [] : {};

  for (let key in object) {
    if (object.hasOwnProperty(key)) {
      newObject[key] =
        typeof object[key] === "object" ? deepCopy(object[key]) : object[key];
    }
  }

  return newObject;
}

//测试
let a = {age: 20};
let b = deepCopy(a);
console.log(b) // {age: 20}
console.log(b.age) // 20
b.age = 18;
console.log(a.age) // 20 证明深拷贝成功

  • 优点:适用于比较复杂的对象,对象转换比较稳定,保留原有的属性

  • 缺点:对象层级越深以及属性越多,性能消耗也会比较高

3、使用库

还可以使用第三方库Lodash中的_.cloneDeep(value),推荐这个库,功能非常强大。