1、浅拷贝
浅拷贝就是拷贝的只是原始对象的属性指向的地址,只是把地址复制了一份。当原始对象的属性指向的地址的内容被修改的时候,克隆的对象的属性的内容也会随之改变。
例如:
var obj = {name: "John",c:{b:1}};
var clone = Object.assign({}, obj); //浅拷贝
obj.c.b=222,
obj.name="ddd";
console.log(clone.c.b); //222
console.log(clone.name); //John
当修改obj的属性c中的属性b的值时,clone的c属性中的b值也发生了变化。这是因为浅拷贝只复制了属性值,而属性值c指向的对象仍然是相同的。因此,修改obj的c属性中的对象时,clone中的c属性中的对象也会被修改。
但是,对于name属性来说,它是一个基本类型的属性,而不是对象。所以,修改obj的name属性时,clone的name属性并不会受到影响,因为基本类型的属性在赋值时会直接复制其值,而不是复制引用。
当使用Object.assign()进行浅拷贝时,它会复制源对象的属性值到目标对象中,但并不会复制属性值所指向的对象的引用。
// 浅拷贝
const shallowCopy = (source) => {
let target = {};
for (x in source) {
target[x] = source[x];
}
return target;
};
2、深拷贝
定义:指在赋值操作过程中,把所复制的对象所占有的内存空间重新分配,复制出一个和原对象完全相同的对象,而对新对象所作的任何修改都不会反映在原对象上。
例如:
const obj = { name: "test" };
const newObj = { ...obj };
// 修改newObj中的name属性
newObj.name = "newTest";
// 此时,obj中的name属性仍然为“test”。
通过上例可以看出,obj和newObj是完全分离的,即发生了深拷贝。
使用示例
const source = {
a: {
b: 'c',
d: { e: 'f' }
}
};
let shallow = shallowCopy(source);
let deep = deepCopy(source);
source.a.b = 'bbb';
source.a.d.e = 'eee';
console.log(shallow); // {a: {b: 'bbb', d: {e: 'eee'}}}
console.log(deep); // {a: {b: 'c', d: {e: 'f'}}}
// 深拷贝
const deepCopy = (source) => {
let target = {};
for (x in source) {
if (typeof source[x]==='object') {
target[x] = deepCopy(source[x]);
} else {
target[x] = source[x];
}
}
return target;
};