js 对象复制
在 JavaScript 中,对象是引用类型,意味着当你复制一个对象时,其实是复制了对象的引用,而不是对象本身。这意味着修改一个复制后的对象会影响到原始对象。因此,如果想要复制一个对象而不影响原始对象,需要进行深拷贝。
浅拷贝
浅拷贝是指只复制对象的第一层属性,而不复制嵌套的对象。在 JavaScript 中,常见的浅拷贝方法有 Object.assign()
和展开运算符(...
)。
使用 Object.assign()
let obj1 = { a: 1, b: 2 };
let obj2 = Object.assign({}, obj1);
console.log(obj2); // { a: 1, b: 2 }
obj2.a = 3;
console.log(obj1); // { a: 1, b: 2 }
console.log(obj2); // { a: 3, b: 2 }
在上面的示例中,Object.assign()
方法创建了一个新的空对象,并将 obj1
的属性复制到新对象中。但是修改 obj2
不会影响 obj1
,因为它们引用的是不同的对象。
使用展开运算符(…)
let obj1 = { a: 1, b: 2 };
let obj2 = { ...obj1 };
console.log(obj2); // { a: 1, b: 2 }
obj2.a = 3;
console.log(obj1); // { a: 1, b: 2 }
console.log(obj2); // { a: 3, b: 2 }
展开运算符(...
) 和 Object.assign()
实现的功能是相似的,都是将一个对象的属性复制到另一个对象中。同样,通过展开运算符复制的对象也是浅拷贝。
深拷贝
深拷贝是指复制整个对象包括嵌套的对象,保证复制后的对象和原始对象互不影响。在 JavaScript 中,扩展不同的库或手动实现深拷贝都是解决这个问题的方法。
使用 Lodash 库
Lodash 是一个流行的 JavaScript 实用工具库,其中包含了深拷贝的方法 _.cloneDeep()
。
const _ = require('lodash');
let obj1 = { a: 1, b: { c: 2 } };
let obj2 = _.cloneDeep(obj1);
console.log(obj2); // { a: 1, b: { c: 2 } }
obj2.b.c = 3;
console.log(obj1); // { a: 1, b: { c: 2 } }
console.log(obj2); // { a: 1, b: { c: 3 } }
在上面的示例中,_.cloneDeep()
方法创建了一个完全独立于原始对象的深拷贝。因此修改 obj2
不会影响 obj1
,它们引用的是不同的对象。
手动实现深拷贝
如果不想依赖第三方库,也可以手动实现深拷贝的函数。
function deepCopy(obj) {
let result = {};
for (let key in obj) {
if (typeof obj[key] === 'object' && obj[key] !== null) {
result[key] = deepCopy(obj[key]);
} else {
result[key] = obj[key];
}
}
return result;
}
let obj1 = { a: 1, b: { c: 2 } };
let obj2 = deepCopy(obj1);
console.log(obj2); // { a: 1, b: { c: 2 } }
obj2.b.c = 3;
console.log(obj1); // { a: 1, b: { c: 2 } }
console.log(obj2); // { a: 1, b: { c: 3 } }
上面的 deepCopy
函数通过递归的方式复制了整个对象的属性,实现了深拷贝的功能。同样,修改 obj2
不会影响 obj1
,因为它们引用的是不同的对象。
结论
在 JavaScript 中,对象的复制有浅拷贝和深拷贝之分。浅拷贝只复制第一层属性,而深拷贝复制整个对象包括嵌套的对象。根据需求选择合适的复制方式,以避免意外的副作用。如果需要深拷贝一个对象,可以使用第三方库如 Lodash 或手动实现深拷贝函数来实现。