在 JavaScript 中,对象是通过引用传递的,这与原始类型(如数字、字符串、布尔值等)的复制行为不同。理解这一点对于避免常见的编程错误非常重要。
当您将一个对象赋值给变量时,实际上是在赋值该对象的引用(内存地址),而不是对象本身。
let user = { name: "John" };
let admin = user; // 复制引用
admin.name = "Pete"; // 通过"admin"引用修改对象
console.log(user.name); // "Pete",通过"user"引用也能看到变化
如果需要复制整个对象,有几种方法可以实现浅拷贝:
Object.assign()
let user = { name: "John", age: 30 };
let clone = Object.assign({}, user);
...
let clone = { ...user };
for..in
循环let clone = {};
for (let key in user) {
clone[key] = user[key];
}
浅拷贝只能复制对象的第一层属性。如果对象包含嵌套对象,这些嵌套对象仍然是引用:
let user = {
name: "John",
sizes: {
height: 182,
width: 50
}
};
let clone = { ...user };
clone.sizes.width = 60; // 也会改变 user.sizes.width
要实现深拷贝(完全独立的副本),可以使用:
JSON.parse(JSON.stringify(obj))
let deepClone = JSON.parse(JSON.stringify(user));
限制:这种方法不能复制函数、Symbol、undefined 等特殊类型。
_.cloneDeep()
let deepClone = _.cloneDeep(user);
function deepClone(obj) {
if (obj === null || typeof obj !== 'object') {
return obj;
}
let clone = Array.isArray(obj) ? [] : {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
clone[key] = deepClone(obj[key]);
}
}
return clone;
}
structuredClone()
) 也是深拷贝的一个选择理解对象引用和复制机制对于编写正确的 JavaScript 代码至关重要,特别是在处理状态管理和数据传递时。