JS 深浅复制:认识不同副本属性的影响
2024-01-17 16:15:58
在 JavaScript 中,复制对象时存在深浅复制之分。深复制会创建目标对象的完全独立副本,而浅复制只会创建目标对象属性的副本,而属性值本身仍指向原来的引用地址。这两种复制方式在不同的场景下具有不同的应用,因此理解它们之间的区别对于提升代码的健壮性和效率至关重要。
首先,我们来了解一下 instanceof 操作符。instanceof 用于判断一个对象是否属于某个类的实例。在复制对象时,我们可以使用 instanceof 来判断副本是否属于与原对象相同的类。如果属于,则表明副本是深复制的;如果不属于,则表明副本是浅复制的。
接下来,我们来看看扩展运算符(...)。扩展运算符可以将一个数组或对象展开成一系列单独的元素或属性。在复制对象时,我们可以使用扩展运算符来创建副本属性。与浅复制不同,扩展运算符创建的副本属性是独立的,不会指向原来的引用地址。
最后,我们再来看一下 Object.assign() 方法。Object.assign() 方法可以将一个或多个源对象的属性复制到目标对象中。在复制对象时,我们可以使用 Object.assign() 方法来创建副本属性。与浅复制不同,Object.assign() 方法创建的副本属性也是独立的,不会指向原来的引用地址。
下面,我们通过一些示例来比较深复制和浅复制的区别:
// 浅复制示例
const originalObject = {
name: 'John Doe',
age: 30,
address: {
street: '123 Main Street',
city: 'Anytown',
state: 'CA',
zip: '12345'
}
};
const shallowCopy = {...originalObject};
// 修改浅副本的属性值
shallowCopy.name = 'Jane Doe';
shallowCopy.address.street = '456 Elm Street';
// 输出原始对象和浅副本
console.log(originalObject);
// { name: 'John Doe', age: 30, address: { street: '456 Elm Street', city: 'Anytown', state: 'CA', zip: '12345' } }
console.log(shallowCopy);
// { name: 'Jane Doe', age: 30, address: { street: '456 Elm Street', city: 'Anytown', state: 'CA', zip: '12345' } }
// 深复制示例
const deepCopy = JSON.parse(JSON.stringify(originalObject));
// 修改深副本的属性值
deepCopy.name = 'John Smith';
deepCopy.address.street = '789 Oak Street';
// 输出原始对象和深副本
console.log(originalObject);
// { name: 'John Doe', age: 30, address: { street: '123 Main Street', city: 'Anytown', state: 'CA', zip: '12345' } }
console.log(deepCopy);
// { name: 'John Smith', age: 30, address: { street: '789 Oak Street', city: 'Anytown', state: 'CA', zip: '12345' } }
在上面的示例中,浅复制只是复制了原对象的属性值,而深复制则复制了原对象的所有属性,包括属性值和对其他对象的引用。因此,修改浅副本的属性值也会影响到原对象,而修改深副本的属性值则不会影响到原对象。
在实际开发中,我们可以根据不同的需求选择不同的复制方式。如果需要创建完全独立的副本,则可以使用深复制;如果只需要复制对象的部分属性,则可以使用浅复制。