面试官:老是问我深浅拷贝问题,自己看文章

面试官:老是问我深浅拷贝问题,自己看文章
最新回答
反音冗

2023-04-29 17:29:09

深浅拷贝是 JavaScript 中处理对象和数组时的重要概念,面试中常被问及。以下是详细解答:

什么是深浅拷贝?

  • 浅拷贝:创建一个新对象,但仅复制原对象的引用地址。若原对象包含嵌套对象,新对象与原对象共享这些嵌套对象的引用。

  • 深拷贝:创建一个完全独立的新对象,包括所有嵌套对象,新对象与原对象互不影响。

如何实现深浅拷贝?

浅拷贝实现方式

  1. Object.assign():合并对象,仅第一层深拷贝。

    let obj1 = { person: {name: "kobe", age: 41}, sports:'basketball' };let obj2 = Object.assign({}, obj1);
  2. 展开运算符 ...:类似 Object.assign()。

    let obj2 = {...obj1};
  3. Array.prototype.concat():数组浅拷贝。

    let arr2 = arr.concat();
  4. Array.prototype.slice():数组浅拷贝。

    let arr3 = arr.slice();

深拷贝实现方式

  1. JSON.parse(JSON.stringify()):简单但无法处理函数、undefined、循环引用。

    let copyObj = JSON.parse(JSON.stringify(obj));
  2. 递归实现:手动实现,处理所有数据类型及循环引用。

    function deepClone(obj, hash = new WeakMap()) { // 处理特殊类型及循环引用 if (obj === null || typeof obj !== "object") return obj; if (hash.has(obj)) return hash.get(obj); let cloneObj = new obj.constructor(); hash.set(obj, cloneObj); for (let key in obj) { if (obj.hasOwnProperty(key)) { cloneObj[key] = deepClone(obj[key], hash); } } return cloneObj;}
  3. 第三方库:如 Lodash 的 _.cloneDeep()。

    let obj2 = _.cloneDeep(obj1);

关键区别

  • 赋值:共享同一内存地址,修改任一变量会影响另一变量。
  • 浅拷贝:仅第一层独立,嵌套对象仍共享。
  • 深拷贝:完全独立,包括所有嵌套对象。

注意事项

  • 循环引用:递归实现需用 WeakMap 避免无限循环。
  • 特殊类型:如 Date、RegExp 需单独处理。
  • 性能:深拷贝递归实现可能影响性能,大数据量时需谨慎。

总结

理解深浅拷贝的核心在于数据存储方式(值类型 vs 引用类型)及内存管理。掌握不同实现方法及其适用场景,能高效应对面试及实际开发中的问题。