如何在对象中传播语法?

时间:2018-05-27 02:01:34

标签: javascript ecmascript-6 spread-syntax

遇到了使用扩展语法创建新对象的概念,如下所示

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"]

任何人都可以向我解释上述情况发生的原因吗?为什么人类的汽车对象会发生变化?在我看来,开发人员很可能在不理解如何避免不一致行为的情况下犯错误

1 个答案:

答案 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"]