前端面试必考!深拷贝和浅拷贝的区别详解

277 阅读2分钟

在前端开发的面试中,深拷贝和浅拷贝的区别是一个高频考点。

今天,我们就来详细探讨一下深拷贝和浅拷贝的区别,以及它们的实现方式。

一、深拷贝和浅拷贝的区别

浅拷贝的特点

只拷贝第一层:浅拷贝只会复制对象的第一层属性。
基本数据类型拷贝值:对于基本数据类型(如 number、string、boolean),直接拷贝值。
引用数据类型拷贝引用:对于引用数据类型(如 object、array),拷贝的是引用而不是实际对象。

深拷贝的特点

多层递归拷贝:深拷贝会递归地复制对象的所有层级。
基本数据类型拷贝值:对于基本数据类型,直接拷贝值。
引用数据类型创建新对象:对于引用数据类型,创建一个新的对象,并递归地将原对象的属性复制到新对象中。

const obj = {
    a: 1,
    b: [1, 2, 3],
    c: {
        d: 4,
        e: 5
    }
}

const newObj = deepClone(obj);
console.log(newObj);
/**
    打印结果:
    {
        a: 1,
        b: [1, 2, 3],
        c: {
            d: 4,
            e: 5
        }
    }
 */

对于浅拷贝来说:
obj.b === newObj.b(引用相同)
obj.c === newObj.c(引用相同)
而对于深拷贝来说,newObj 的所有属性都是新的引用,与原对象完全独立。
二、浅拷贝的实现方式

    1. 展开运算符
      使用 ES6 提供的展开运算符(...)可以实现浅拷贝:
const newObj = { ...obj };
    1. Object.assign
      Object.assign 是一个静态方法,可以将一个或多个对象的可枚举自有属性合并到目标对象中:
const newObj = Object.assign({}, obj1, obj2, ...);
    1. for..in + Object.prototype.hasOwnProperty
      通过 for..in 循环和 hasOwnProperty 方法手动实现浅拷贝:
function shallowClone(obj) {
    const newObj = {};
    for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            newObj[key] = obj[key];
        }
    }
    return newObj;
}

三、深拷贝的实现方式

    1. JSON.parse + JSON.stringify
      通过 JSON.stringify 将对象序列化为 JSON 字符串,再通过 JSON.parse 将其解析为新的对象:
const newObj = JSON.parse(JSON.stringify(obj));

缺点:
无法处理循环引用。
不支持 function 和 undefined。
无法复制某些对象类型(如 Date、RegExp、Map、Set 等)。
2. 使用第三方库
使用 lodash 等第三方库可以轻松实现深拷贝:

const _ = require('lodash');
const newObj = _.cloneDeep(obj);
    1. 手动实现深拷贝
      通过递归手动实现深拷贝:
const isObj = (target) => typeof target === 'object' && target !== null;
function deepClone(obj, hash = new WeakMap()) {
    if (!isObj(obj)) return obj;
    if (hash.has(obj)) return hash.get(obj);
    const target = new obj.constructor();
    hash.set(obj, target);
    Object.keys(obj).forEach((key) => {
        target[key] = deepClone(obj[key], hash);
    });
    return target;
}

五、总结

深拷贝和浅拷贝是前端开发中常见的概念,掌握它们的区别和实现方式对于面试和实际开发都非常重要。

希望这篇文章能帮助你更好地理解深拷贝和浅拷贝!如果你对上述内容有任何疑问,欢迎在评论区留言讨论!