简体   繁体   English

什么时候需要使用Object.assign()方法来复制对象的实例?

[英]When is it necessary to use the Object.assign() method to copy an instance of an object?

The following is an example scenario I made up for my own practice of this problem. 以下是我自己练习此问题的示例场景。 If you want to skip straight to the technical details, please see 'Technical Details' below. 如果您想直接跳到技术细节,请参阅下面的“技术细节”。

I have a personal project I've been working on to learn JavaScript. 我有一个个人项目,我一直在努力学习JavaScript。 Basically, the user can design a shoe by picking available options. 基本上,用户可以通过挑选可用选项来设计鞋子。

The trick is that the left and right shoe must have the same size, among other properties, but things like color, shoe lace texture, etc. can be independent properties per shoe. 诀窍在于左右鞋必须具有相同的尺寸,以及其他属性,但是诸如颜色,鞋带纹理等的东西可以是每个鞋子的独立属性。 (I figured this was a decent way for me to practice object manipulation and inheritance). (我认为这对我来说是一种体面的方式来练习对象操作和继承)。

The user starts off with designing the right shoe; 用户开始设计合适的鞋子; when the "swap" button is clicked to look at the left shoe, the user currently sees a copy of the right shoe (but inverted). 当单击“交换”按钮以查看左鞋时,用户当前看到右鞋的副本(但是倒置)。 Only on the first swapping of shoes is the left shoe generated and made an exact copy of the right shoe. 只有在第一次换鞋时才生成左鞋,并制作了正确鞋子的精确副本。 From then onwards, unique options per shoe orientation are preserved. 从那时起,每个鞋子方向的独特选项得以保留。 Then, if the user makes specific changes to that left-shoe model, and then switches to the right shoe, the user is supposed to see the exact same right shoe that they had originally designed before they clicked the "swap" button. 然后,如果用户对该左鞋模型进行了特定的更改,然后切换到右鞋,则用户应该在他们点击“交换”按钮之前看到他们最初设计的完全相同的右鞋。

So if their right shoe had red laces, they switch to the left shoe view and make the left shoe have a blue lace, then when switching back to the right shoe the user should see red laces! 因此,如果他们的右鞋有红色鞋带,他们会切换到左侧鞋子视图并使左侧鞋子有蓝色花边,然后当切换回右侧鞋子时,用户应该看到红色鞋带!


Technical Details 技术细节

When I was writing the code for my main project I was running into trouble with the unique options being perserved. 当我为我的主项目编写代码时,遇到了独特的选项,我遇到了麻烦。 For example, if I made the laces green for the left shoe, the right shoe would always have green laces. 例如,如果我为左鞋制作鞋带绿色,那么右鞋总是会有绿色鞋带。 Troubleshooting down to the problem was easy because the only time the right shoe was losing it's unique options, such as a red lace, was when I would set the lace color for the left shoe. 对问题进行故障排除很容易,因为正确的鞋子失去它的唯一选择,例如红色蕾丝,就是我为左鞋设置蕾丝颜色的时候。

console.log("THE RIGHT LACE BEFORE: " + rightShoe.laceId);
leftShoe.laceId = 'green';
console.log("THE RIGHT LACE AFTER: " + rightShoe.laceId);

What would log to the console was: 记录到控制台的是:

THE RIGHT LACE BEFORE: red 之前的正确的蕾丝:红色

THE RIGHT LACE AFTER: green 正确的蕾丝后:绿色

Even though I wasn't changing the rightShoe , it was being changed whenever I changed the leftShoe property. 即使我没有更改rightShoe ,每当我更改leftShoe属性时它都会被更改。

So I went back to where I first define the leftShoe object, which is when the user clicks "swap" for the first time in the life of the script (My amateur thought was why propagate and fill the leftShoe object if the user possibly never customizes the left shoe? Maybe it's being unnecessarily stingy with data, I don't know). 所以我回到了我第一次定义leftShoe对象的地方,这是用户在脚本生命周期中第一次点击“交换”的时候(我的业余想法是为什么传播并填充leftShoe对象,如果用户可能永远不会定制的话)左边的鞋子?也许是对数据不必要的吝啬,我不知道)。 From then onward, I never redefined the leftShoe to be a copy of rightShoe or vice versa. 从那时起, 我从来没有重新定义了leftShoe是副本rightShoe反之亦然。 I figured that I was getting hung up by the fact that I was probably doing object referencing and, just like with other languages, I was changing the reference and not the value. 我认为我可能因为我可能正在进行对象引用而被挂起,就像其他语言一样,我正在改变引用而不是值。

Before coming to SO with my troubles, I wanted to make a JSFiddle to recreate the problem. 在遇到麻烦之前,我想制作一个JSFiddle来重现问题。 Being that my project is lengthy (around ~1500 lines, including some THREE.js for graphics), I did my best to emulate the process. 由于我的项目很长(约1500行,包括一些THREE.js用于图形),我尽力模仿这个过程。 And so here it is . 所以就是这样

Except the JSFiddle worked exactly as I expected it to! 除了JSFiddle完全按照我的预期工作! The left model preserved it's unique attribute and data set to that attribute. 左侧模型保留了它对该属性的唯一属性和数据集。 So, I did a little more digging and read about the Object.assign() method. 所以,我做了一些关于Object.assign()方法的挖掘和阅读。 So in my original project code ( not the fiddle), I changed this: 所以在我原来的项目代码( 不是小提琴)中,我改变了这个:

leftShoe = rightShoe;

to this: 对此:

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

As excited as I am to have finally gotten this to work, I am equally amused and perplexed because I don't understand why my JSFiddle didn't need the assign() method but my identical project code did. 我很高兴终于让它工作了,我同样感到好笑和困惑,因为我不明白为什么我的JSFiddle不需要assign()方法但我的相同项目代码确实如此。 Thank you. 谢谢。

Object.Assign makes a new COPY of the left shoe, including all enumerable OWN properties. Object.Assign生成左侧鞋子的新COPY,包括所有可枚举的OWN属性。 When you use leftshoe = rightshoe, you are making a REFERENCE to the left shoe. 当你使用leftshoe = rightshoe时,你正在对左鞋进行参考。 A reference points to the same object, not a NEW COPY. 引用指向同一个对象,而不是新复制。 Thus changing a property of the reference is actually changing the original, as you noted. 因此,如您所述,更改引用的属性实际上正在更改原始属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM