深拷贝、浅拷贝

112 阅读1分钟

1. 区别

浅拷贝:复制基本类型和引用类型

深拷贝:引用类型所指向的内存空间也完全拷贝

2. 浅拷贝的实现方式

2.1 Object.assign(target, ...sources)

把对象的可枚举属性拷贝给目标对象

2.2 展开运算符...

与Object.assign相同

2.3 Array.prototype.concat()

2.4 Array.prototype.slice()

3. 深拷贝的实现方式

3.1.JSON.parse(JSON.stringify())

let arr = [1, 3, { username: 'liangliang' }];
JSON.parse(JSON.stringify(arr)); // 深拷贝,会为对象开辟新的栈空间

优点

  • 可以解决对象内部循环引用的问题,JSON.stringify内部做了循环引用的检测

缺点

  • 会抛弃对象的constructor,无论原本的构造函数是什么,在此之后都会变成Object
  • 但是这样对正则表达式处理后会变成空对象,数组或者对象中的函数变为null

3.2 jQuery.extend

jQuery.extend( [deep], target, object1 [, objectN ] )

3.3 MessageChannel [2021.3.2]

function deepCopy(obj) {
    return new Promise((resolve) => {
        const {port1, port2} = new MessageChannel();
        port2.onmessage = ev => resolve(ev.data);
        port1.postMessage(obj);
    });
}
​
deepCopy(obj).then((copy) => {           // 请记住`MessageChannel`是异步的这个前提!
    let copyObj = copy;
    console.log(copyObj, obj)
    console.log(copyObj == obj)
});

可以拷贝undefined和循环引用的对象,但是有函数的对象还是报错

参考

juejin.im/post/684490…
github.com/mqyqingfeng…(内含jQuery的实现)
segmentfault.com/a/119000001…(内含循环深拷贝)