JS常见拷贝方法:深入浅出解析浅拷贝、深拷贝与结构拷贝
2023-10-03 09:09:27
浅拷贝
浅拷贝是指只拷贝对象或数组的第一层属性,而不会递归地拷贝嵌套的对象和数组。
浅拷贝方法 :
-
Object.assign():Object.assign()方法可以将一个或多个源对象的属性拷贝到目标对象。它只会拷贝源对象的浅层属性,不会递归地拷贝嵌套的对象和数组。
-
扩展运算符(...):扩展运算符(...)可以将一个对象或数组的属性拷贝到另一个对象或数组中。它只会拷贝浅层属性,不会递归地拷贝嵌套的对象和数组。
浅拷贝示例 :
const obj1 = {
name: 'John',
age: 30,
address: {
street: '123 Main Street',
city: 'New York',
state: 'NY'
}
};
const obj2 = Object.assign({}, obj1);
console.log(obj2);
// 输出:{ name: 'John', age: 30, address: { street: '123 Main Street', city: 'New York', state: 'NY' } }
const obj3 = { ...obj1 };
console.log(obj3);
// 输出:{ name: 'John', age: 30, address: { street: '123 Main Street', city: 'New York', state: 'NY' } }
在上面的示例中,我们使用Object.assign()方法和扩展运算符(...)对obj1对象进行了浅拷贝。可以看到,obj2和obj3都是obj1的浅拷贝,它们都具有与obj1相同的浅层属性。但是,obj2和obj3的address属性指向的是同一个对象,这意味着对obj2或obj3的address属性所做的任何更改都会反映在另一个对象上。
深拷贝
深拷贝是指递归地拷贝对象或数组的所有属性,包括嵌套的对象和数组。
深拷贝方法 :
-
JSON.parse(JSON.stringify()):JSON.parse(JSON.stringify())方法可以将一个对象或数组序列化为JSON字符串,然后再将其解析回一个对象或数组。这种方法可以实现对象的深拷贝。
-
使用递归:我们可以使用递归函数来实现对象的深拷贝。递归函数会遍历对象或数组的所有属性,并对每个属性进行深拷贝。
深拷贝示例 :
const obj1 = {
name: 'John',
age: 30,
address: {
street: '123 Main Street',
city: 'New York',
state: 'NY'
}
};
const obj2 = JSON.parse(JSON.stringify(obj1));
console.log(obj2);
// 输出:{ name: 'John', age: 30, address: { street: '123 Main Street', city: 'New York', state: 'NY' } }
function deepCopy(obj) {
if (typeof obj !== 'object' || obj === null) {
return obj;
}
if (Array.isArray(obj)) {
return obj.map(deepCopy);
}
const newObj = {};
for (const key in obj) {
newObj[key] = deepCopy(obj[key]);
}
return newObj;
}
const obj3 = deepCopy(obj1);
console.log(obj3);
// 输出:{ name: 'John', age: 30, address: { street: '123 Main Street', city: 'New York', state: 'NY' } }
在上面的示例中,我们使用JSON.parse(JSON.stringify())方法和递归函数实现了obj1对象的深拷贝。可以看到,obj2和obj3都是obj1的深拷贝,它们具有与obj1相同的属性,并且这些属性指向的是不同的对象。这意味着对obj2或obj3的任何属性所做的更改都不会反映在另一个对象上。
结构拷贝
结构拷贝是指只拷贝对象或数组的结构,而不拷贝其值。结构拷贝通常用于创建对象或数组的副本,以便对其进行修改,而不会影响原始对象或数组。
结构拷贝方法 :
-
Object.create():Object.create()方法可以创建一个新对象,该对象的原型是另一个对象。新对象具有与原型对象相同的结构,但不会拷贝原型对象的值。
-
使用扩展运算符(...):扩展运算符(...)可以将一个对象或数组的结构拷贝到另一个对象或数组中。它只拷贝结构,不会拷贝值。
结构拷贝示例 :
const obj1 = {
name: 'John',
age: 30,
address: {
street: '123 Main Street',
city: 'New York',
state: 'NY'
}
};
const obj2 = Object.create(obj1);
console.log(obj2);
// 输出:{}
const obj3 = { ...obj1 };
console.log(obj3);
// 输出:{ name: undefined, age: undefined, address: undefined }
在上面的示例中,我们使用Object.create()方法和扩展运算符(...)对obj1对象进行了结构拷贝。可以看到,obj2和obj3都是obj1的结构拷贝,它们具有与obj1相同的结构,但没有拷贝obj1的值。这意味着对obj2或obj3的任何属性所做的更改都不会影响obj1。
总结
在JavaScript中,我们经常需要对对象和数组进行拷贝操作。拷贝方法主要分为浅拷贝、深拷贝和结构拷贝。浅拷贝只拷贝对象或数组的第一层属性,而深拷贝会递归地拷贝对象或数组的所有属性,包括嵌套的对象和数组。结构拷贝只拷贝对象或数组的结构,而不拷贝其值。
在实际开发中,我们需要根据不同的需求选择合适的拷贝方法。如果只需要拷贝对象或数组的第一层属性,那么可以使用浅拷贝方法。如果需要拷贝对象或数组的所有属性,包括嵌套的对象和数组,那么可以使用深拷贝方法。如果只需要拷贝对象或数组的结构,而不拷贝其值,那么可以使用结构拷贝方法。