深拷贝、浅拷贝

深拷贝、浅拷贝

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())

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

优点

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

缺点

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

3.2 jQuery.extend

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

3.3 MessageChannel [2021.3.2]

1
2
3
4
5
6
7
8
9
10
11
12
13
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和循环引用的对象,但是有函数的对象还是报错

参考

https://juejin.im/post/6844904197595332622
https://github.com/mqyqingfeng/Blog/issues/33(内含jQuery的实现)
https://segmentfault.com/a/1190000016672263(内含循环深拷贝)

作者

Liang

发布于

2020-10-31

更新于

2021-12-24

许可协议


评论