Javascript Object.assign()和Spread属性仍在变化

Javascript Object.assign()和Spread属性仍在变化,javascript,typescript,ecmascript-6,Javascript,Typescript,Ecmascript 6,我试图将数组元素的值赋给对象。在第一次尝试类似的东西之后,例如bar=foo[0];我发现,由于具有相同的引用,对bar的任何更改也会更改foo[0] 太棒了,没人想,在阅读了不变性和ES6 Object.assign方法和spread属性之后,我认为它会解决这个问题。然而,在这种情况下,情况并非如此。我错过了什么 编辑:很抱歉对accountTypes的混淆,我修复了这个示例。 另外,我希望保留设置的类结构,因此让copy=JSON.parseJSON.stringifyoriginal;这不

我试图将数组元素的值赋给对象。在第一次尝试类似的东西之后,例如bar=foo[0];我发现,由于具有相同的引用,对bar的任何更改也会更改foo[0]

太棒了,没人想,在阅读了不变性和ES6 Object.assign方法和spread属性之后,我认为它会解决这个问题。然而,在这种情况下,情况并非如此。我错过了什么

编辑:很抱歉对accountTypes的混淆,我修复了这个示例。 另外,我希望保留设置的类结构,因此让copy=JSON.parseJSON.stringifyoriginal;这不是我想要的

//this object will change according to a selection
currentPreset;

//this should remain unchanged
presets: {name: string, settings: Settings}[] = [];


  ngOnInit()
  {
    this.currentPreset = {
      name: '',
      settings: new Settings()
    }

    this.presets.push({name: 'Preset1', settings: new Settings({
        settingOne: 'foo',
        settingTwo: false,
        settingThree: 14
      })
    });

  }

 /**
  * Select an item from the `presets` array and assign it, 
  * by value(not reference), to `currentPreset`.
  * 
  * @Usage In an HTML form, a <select> element's `change` event calls 
  * this method to fill the form's controls with the values of a
  * selected item from the `presets` array. Subsequent calls to this
  * method should not affect the value of the `presets` array.
  *
  * @param value - Expects a numerical index or the string 'new'
  */
  setPreset(value)
  {
    if(value == 'new')
    {
      this.currentPreset.name = '';
      this.currentPreset.settings.reset();
    }
    else
    {
      this.currentPreset = {...this.presets[value]};
      //same as above
      //this.currentPreset = Object.assign({}, this.presets[value]);
    }
  }

您必须进行深度复制,这是最简单的方法:

let copy = JSON.parse(JSON.stringify(original));

这并不能真正回答问题,但由于我试图不变异的对象中没有嵌套的属性,因此我在属性级别调用赋值,这里的浅层副本就可以了

setPreset(value)
  {
    if(value == 'new')
    {
      this.currentPreset.name = '';
      this.currentPreset.settings.reset();
    }
    else
    {
      this.currentPreset.name = this.presets[value].name;
      this.currentPreset.privileges = Object.assign(new Settings(), 
                                         this.presets[value].settings);
    }
  }
一个更好的解决方案,因为我正在创建一个新的设置,可能是将此逻辑移动到一个设置类方法,并在构造函数中调用它; 这将创建一个新对象,而不引用原始的旧对象

如果要对数组执行此操作,请尝试使用[]执行相同的操作


我最近也遇到了同样的问题,我不明白为什么我的一些对象正在更改它们的属性。我不得不修改代码以避免变异。这里的一些答案帮助我后来理解了,比如这篇很棒的文章:


我推荐它。作者给出了许多例子和有用的库,在嵌入属性方面可以比Object.assign更好。

您能提供一个更完整或更好的例子吗?什么是帐户类型?什么是价值?您不希望变异的值是什么,变异前是什么,变异后是什么?使用这些运算符,您正在对设置进行阴影复制,这些设置在所有更新中都是相同的实例。使用object spread或object.assign将仅创建浅层副本。因此,对该副本的属性进行变异仍然会更改原始副本中的相同属性。您可能需要尝试创建深度副本。下面的答案展示了几种方法。请小心,因为JSON只存储普通对象,而不是具有自定义原型的特定类型的对象。老实说,我不知道这是否与OP的使用有关,因为它们没有显示足够的代码,但如果存在设置对象或任何其他类型的自定义对象,那么这种类型的深度复制将不会保留自定义对象类型/原型。@Luis,谢谢你的回答。我忘了提到它,但我确实想保留设置对象,正如jfriend00指出的那样。
let copy = original.map(item => Object.assign([], ...item));