let a = {
name: 'Dobby',
age: 20
};
let b = a;
a.age = 10;
b.name = ' qzhang';
console.log(b.age); // output:10
console.log(a.name); // output:qzhang
从上面例子可以看出,当我们把一个对象赋值给一个变量的时候,两者的值会是同一个引用,其中一方改变,另一方也会改变。
通常我们在开发的过程中不希望出现这样的问题,我们可以使用浅拷贝来解决这个问题。
浅拷贝
首先,可以通过 Object.assign 来解决这个问题。
let a = {
name: 'Dobby',
age: 20
};
let b = Object.assign({}, a);
a.age = 10;
b.name = ' qzhang';
console.log(b.age); // output:20
console.log(a.name); // output:Dobby
还可以使用 展开运算符(...)来解决。
let a = {
name: 'Dobby',
age: 20
};
let b = {...a};
a.age = 10;
b.name = ' qzhang';
console.log(b.age); // output:20
console.log(a.name); // output:Dobby
通常浅拷贝可以解决大部分问题,但当我们在如下例子中对象中还有对象的话,就需要深拷贝了。
let a = {
name: 'Dobby',
age: 20,
job: {
first: 'web'
}
};
let b = {...a};
a.age = 10;
a.job.first = 'java';
console.log(b.age); // output:20
console.log(b.job.first); // output:java
深拷贝
通常可以通过 JSON.parse(JSON.stringify(object)) 来解决。
let a = {
name: 'Dobby',
age: 20,
job: {
first: 'web'
}
};
let b = JSON.parse(JSON.stringify(a));
a.job.first = 'java';
console.log(b.job.first); // output:web
但该方法有局限性:
1. 会忽略 undefined
2. 会忽略 symbol
3. 不能序列化函数
4. 不能解决循环引用的对象
通常情况下,复杂数据都是可以序列化的,所以这个函数可以解决大部分问题,并且该函数是内置函数中处理深拷贝性能最快的。如果数据中有 undefined、symbol、函数三种情况,可以使用 lodash 的深拷贝函数。