Javascript 何时需要使用Object.assign()方法复制对象的实例?

Javascript 何时需要使用Object.assign()方法复制对象的实例?,javascript,jquery,object,constructor,Javascript,Jquery,Object,Constructor,下面是我为自己解决这个问题而编写的一个示例场景。如果您想直接跳到技术细节,请参阅下面的“技术细节”。 我有一个学习JavaScript的个人项目。基本上,用户可以通过选择可用选项来设计鞋子 诀窍在于左右鞋必须具有相同的尺寸和其他属性,但颜色、鞋带纹理等可以是每只鞋的独立属性。(我觉得这是我练习对象操作和继承的一种不错的方式) 用户从设计合适的鞋开始;当点击“交换”按钮查看左鞋时,用户当前会看到右鞋的副本(但反向)只有在第一次交换鞋子时,才会生成左鞋子并制作右鞋子的精确副本。从那时起,将保留每个鞋

下面是我为自己解决这个问题而编写的一个示例场景。如果您想直接跳到技术细节,请参阅下面的“技术细节”。

我有一个学习JavaScript的个人项目。基本上,用户可以通过选择可用选项来设计鞋子

诀窍在于左右鞋必须具有相同的尺寸和其他属性,但颜色、鞋带纹理等可以是每只鞋的独立属性。(我觉得这是我练习对象操作和继承的一种不错的方式)

用户从设计合适的鞋开始;当点击“交换”按钮查看左鞋时,用户当前会看到右鞋的副本(但反向)只有在第一次交换鞋子时,才会生成左鞋子并制作右鞋子的精确副本。从那时起,将保留每个鞋方向的唯一选项。然后,如果用户对该左鞋型号进行特定更改,然后切换到右鞋,则用户将看到与他们在单击“交换”按钮之前最初设计的右鞋完全相同的右鞋

因此,如果他们的右鞋有红色鞋带,他们会切换到左鞋视图并使左鞋有蓝色鞋带,然后当切换回右鞋时,用户应该会看到红色鞋带


技术细节

当我为我的主要项目编写代码时,我遇到了一个麻烦,因为我保留了一些独特的选项。例如,如果我将左鞋的鞋带设为绿色,则右鞋的鞋带将始终为绿色。解决问题很容易,因为只有在我为左脚鞋设置花边颜色时,右脚鞋才会失去其独特的选项,如红色花边

console.log("THE RIGHT LACE BEFORE: " + rightShoe.laceId);
leftShoe.laceId = 'green';
console.log("THE RIGHT LACE AFTER: " + rightShoe.laceId);
将记录到控制台的是:

右前花边:红色

正确的花边后:绿色

尽管我没有更改
rightShoe
,但每当我更改
leftShoe
属性时,它都会更改

所以我回到了我第一次定义
leftShoe
对象的地方,这是用户在脚本生命周期中第一次单击“swap”(我的业余爱好者认为,如果用户可能从未定制过左鞋,为什么要传播和填充
leftShoe
对象?可能是因为它对数据不必要的吝啬,我不知道).从那时起,我从未将
leftShoe
重新定义为
rightShoe
的副本,反之亦然。我想我可能正在进行对象引用,就像其他语言一样,我正在更改引用,而不是值,这让我很困惑

在我遇到麻烦之前,我想做一个JSFIDLE来重现这个问题。由于我的项目很长(大约1500行,包括一些THREE.js的图形),我尽了最大努力来模拟这个过程。如此

除了JSFIDLE完全按照我的预期工作之外!左边的模型保留了它的唯一属性和该属性的数据集。因此,我对Object.assign()方法进行了进一步的挖掘和阅读。因此,在我最初的项目代码(不是FIDLE)中,我更改了以下内容:

leftShoe = rightShoe;
为此:

leftShoe = Object.assign({}, rightShoe);

虽然我很兴奋终于实现了这一点,但我同样感到有趣和困惑,因为我不明白为什么我的JSFIDLE不需要
assign()
方法,但我的项目代码相同。谢谢。

Object.Assign创建左鞋的新副本,包括所有可枚举的自身属性。当使用leftshoe=rightshoe时,您正在对左鞋进行引用。引用指向同一对象,而不是新副本。因此更改引用的属性实际上是错误的正如您所指出的,更改原稿。

谢谢!因此我不得不问,为什么我链接的JSFIDLE不是这样?我使用参考赋值,但仍然能够进行更改。查看我的FIDLE的第35行,然后查看我在观看输出时所做的按钮。我觉得小提琴好像坏了。当它应该保持9990。非常感谢现在在react with Redux中使用它更有意义。在第一种情况下,两个变量引用同一个对象。在第二种情况下,您正在创建一个新对象(
{}
)并使用
对象复制所有属性。赋值
。对一个对象进行变异将不会反映在另一个对象中。@Bergi谢谢,我认为这对我来说现在是有意义的。其他语言非常标准。但现在让我不感兴趣的是我的JSFiddle。如果你看看我链接的Fiddle第35行的引用赋值,你会看到在左边,选项的值被改变,与它是一个被引用的对象这一事实无关。你没有,你写了两个
控制台。日志
以相同的值结束。没有什么区别。不管怎样,我只是看不出在那把小提琴中有什么意外的行为。也许把你得到的输出放在你的问题中,并指向您期望的其他内容所在的行。
leftChoice.id
设置为该值后为什么不立即变为444?当然,
right choice.id
现在也会变为444,因为它们仍然指向同一对象。当您指定给它时,它会改变它的值。很可能您已经覆盖了它(可能通过指向同一对象的
rightChoice
)进行记录。