在讨论深拷贝和浅拷贝之前,我们先来了解一下ECMAScript 的数据类型
ECMAScript 的数据类型
基本数据类型:
undefined,boolean,number,string,null
基本数据类型存放在栈中,数据大小确定,内存空间大小可以分配,是直接按值存放的,所以可以直接访问。
引用类型:
引用类型(object)是存放在堆内存中的,变量实际上是一个存放在栈内存的指针,这个指针指向堆内存中的地址。每个空间大小不一样,要根据情况开进行特定的分配。
深拷贝和浅拷贝的区别
浅拷贝:
- 只复制一层对象的属性,并不包括对象里面的为引用类型的数据;
- 增加了一个指针指向已存在的内存地址
深拷贝:
- 对对象以及对象的所有子对象进行拷贝。
- 增加了一个指针并且申请了一个新的内存,使这个增加的指针指向这个新的内存。
- 使用深拷贝的情况下,释放内存的时候不会因为出现浅拷贝时释放同一个内存的错误。
实现浅拷贝的方式:
Object.assign(target, …sources)
1
2
3
4
5
6let a = {
name: 'join'
}
let b = Object.assign({}, a)
a.name = 'jack'
console.log(b.name) // join扩展运算符 …
1
2
3
4
5
6let a = {
name: 'join'
}
let b = Object.assign(···a)
a.name = 'jack'
console.log(b.name) // join遍历+hasOwnProperty()
1
2
3
4
5
6
7
8
9
10function shallowCopy(object) {
// 遍历 object,并且判断是 object 的属性才拷贝
for (let key in object) {
if (object.hasOwnProperty(key)) {
newObject[key] = object[key];
}
}
return newObject;
}
实现深拷贝的方式:
JSON.parse(JSON.stringify(object))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20let obj1 = {
'name' : 'zhangsan',
'age' : '18',
'language' : [1,[2,3],[4,5]],
};
let obj2 = JSON.parse(JSON.stringify(obj1))
obj1.language[2] = [7,8]
console.log(obj1)
// {
// 'name' : 'zhangsan',
// 'age' : '18',
// 'language' : [1,[2,3],[7,8]],
//}
console.log(obj2)
// {
// 'name' : 'zhangsan',
// 'age' : '18',
// 'language' : [1,[2,3],[5,6]],
//}递归+hasOwnProperty()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36let obj1 = {
name: "zhangsan",
age: "18",
language: [1, [2, 3], [4, 5]],
};
function deepCopy(object) {
if (!object || typeof object !== "object") return;
let newObject = Array.isArray(object) ? [] : {};
for (let key in object) {
if (object.hasOwnProperty(key)) {
newObject[key] =
typeof object[key] === "object"
? deepCopy(object[key])
: object[key];
}
}
return newObject;
}
let obj2 = deepCopy(obj1)
obj1.language[2] = [7,8]
console.log(obj1)
// obj1 = {
// name: "zhangsan",
// age: "18",
// language: [1, [2, 3], [7, 8]],
// };
console.log(obj2)
// obj2 = {
// name: "zhangsan",
// age: "18",
// language: [1, [2, 3], [4, 5]],
// };
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 解忧杂货店小店员!