浅拷贝与深拷贝

浅拷贝与深拷贝

原始类型的复制

message 复制到 phrase,这样messagephrase就是两个独立的变量,互不干扰。原始类型是存在内存的栈里。

1
2
let message = "Hello!";
let phrase = message;

对象的复制引用

看一段代码,显然ab都指向同一块内存地址

1
2
3
4
5
let a = {};
let b = a; // 复制引用

alert( a == b ); // true,都引用同一对象
alert( a === b ); // true

对象的浅拷贝

遍历一维对象(我自己取的名字)的所有属性,搬运到新建的空对象上,但是如果对象里面嵌套了对象,这一招就不管用了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
let user = {
name: "John",
age: 30
};

let clone = {}; // 新的空对象

// 将 user 中所有的属性拷贝到其中
for (let key in user) {
clone[key] = user[key];
}

// 现在 clone 是带有相同内容的完全独立的对象
clone.name = "Pete"; // 改变了其中的数据

alert( user.name ); // 原来的对象中的 name 属性依然是 John

javascript还提供了Object.assign这个方法。使用方法如下:

1
2
3
4
5
6
7
8
9
let user = { name: "John" };

let permissions1 = { canView: true };
let permissions2 = { canEdit: true };

// 将 permissions1 和 permissions2 中的所有属性都拷贝到 user 中
Object.assign(user, permissions1, permissions2);

// 现在 user = { name: "John", canView: true, canEdit: true }

对象的深拷贝

可以使用递归的方式实现深层拷贝

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
let user = {
name: "John",
sizes: {
height: 182,
width: 50
}
};
function deepClone(obj){
let newObj={};
for(let key in obj){
if(typeof obj[key]==='Object'&& obj[key]!==null){
newObj[key]=deepClone(obj[key]);
}else{
newObj[key]=obj[key];
}
}
return newObj;
}
deepClone(user);

很蓝很蓝啦~~

还可以使用loadsh库的_.cloneDeep(obj)