对象的浅复制与深复制

前言

虽然之前也知道浅复制是复制引用,深复制是新建一个对象,但是今天发现对于一些特殊类型还可以更高效的实现,因此整体梳理下作个备忘。

概述

之所以存在浅复制与深复制的概念,主要是因为变量在内存中的存放机制不同。
基本类型直接放栈内存中,而引用类型是引用(指针)放在栈内存,主体数据放在堆内存中。对于堆栈内存的理解,可以简单类比为库房与前台店面,小东西可以直接店面展示(例如便利店),大物件只能放个模型对应具体哪一户(例如售楼处)。示例图如下:

堆栈内存示例图

详述

所谓浅复制与深复制主要针对引用类型,因为基本类型赋值就是值传递,而引用类型赋值是传递引用(指针)。我们可以把该对象的引用赋值给多个变量,他们指向同一个堆内存中的位置,只要其中一个改变了对象数据,其他的得到的也是变化后的,因为大家都指向一个堆内存中的数据。

为了阻断这种影响,那么只能在堆内存中也复制一份,各自引用指向各自的堆数据。

值不是 undefined,function,symbol 的对象

1
2
3
4
5
6
7
8
9
function deepCopy(obj) {
return JSON.parse(JSON.stringify(obj));
}
// 示例
let a = [0, 1, [2, 3], 4],
b = deepCopy(a);
a[0] = 1;
a[2][0] = 1;
console.log(a, b);

深拷贝

1
2
3
4
5
6
7
8
9
10
11
12
13
function deepCopy(obj) {
var cloneObj = Array.isArray(obj) ? [] : {};
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
if (typeof obj[key] == "object") {
// 递归
cloneObj[key] = deepCopy(obj[key]);
} else {
cloneObj[key] = obj[key];
}
}
}
}

后记

图片来源