遇到了使用扩展语法创建新对象的概念,如下所示
const human = { age: 20 };
const john = { ...human };
john.age = 10;
console.log(human.age); // 20
console.log(john.age); // 10
如上所示,人类对象可以保留原始值。现在看看下面的代码:
const human = { age: 20, cars: ["toyota", "honda"] };
const john = { ...human };
john.cars[1] = "camero";
console.log(human.cars); // ["toyota", "camero"]
console.log(john.cars); // ["toyota", "camero"]
任何人都可以向我解释上述情况发生的原因吗?为什么人类的汽车对象会发生变化?在我看来,开发人员很可能在不理解如何避免不一致行为的情况下犯错误
答案 0 :(得分:3)
对象cd
仅包含包含human
的数组的引用。使用spread运算符复制对象时,还要复制引用,这意味着["toyota", "honda"]
具有相同的引用,因此john
与{{1}是相同的数组}}
因此,如果您修改john.cars
,则还会修改human.cars
,因为它们是相同的数组。如果要克隆数组,也可以使用扩展运算符执行此操作:
john.cars
如果克隆具有对象属性的对象,您还会看到此类行为:
human.cars
这是因为扩展运算符只将引用复制到名称对象,而不是名称对象本身。因此,修改一个会修改另一个,因为它们是同一个对象。这被称为浅层克隆。如果您想避免这种混淆,则需要执行深度克隆。
最简单的方法是转换为JSON然后转换回来:
const human = { age: 20, cars: ["toyota", "honda"] };
const john = { ...human };
john.cars = [ ... human.cars ];
john.cars[1] = "camero";
console.log(human.cars); // ["toyota", "honda"]
console.log(john.cars); // ["toyota", "camero"]