Object.assign()和Spread属性仍然会改变原始属性

时间:2018-04-24 21:07:10

标签: javascript typescript ecmascript-6

我试图将数组元素的值赋给对象。在第一次尝试之类的事情之后,例如bar = foo[0];我发现bar的任何更改都会因foo[0]而改变let copy = JSON.parse(JSON.stringify(original));

太棒了,没想到,在阅读 immutability 和ES6 Object.assign()方法和传播属性时,我以为它会解决这个问题。但是,在这种情况下它并没有。我错过了什么?

编辑:抱歉 accountTypes 混淆,我修复了这个例子。 另外,我想保留设置的类结构,因此在这种情况下//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]); } } 并不是我真正想要的。

version: '3'
services:
  myvault:
        image: vault
        container_name: myvault
        ports:
          - "192.168.99.100:8200:8200"
        environment:
           VAULT_SERVER: "http://192.168.99.100:8200"
           TOKEN: mysuper-secret-vault-token
        volumes:
          - ./file:/vault/file:rw
          - ./config:/vault/config:rw
        cap_add:
          - IPC_LOCK

4 个答案:

答案 0 :(得分:1)

你必须做一个深层复制,这是最简单的方法:

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

答案 1 :(得分:0)

这并没有真正回答这个问题,但由于我试图不变异的对象并没有嵌套属性,我在属性级调用赋值,在这里调用浅拷贝很好。

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);
    }
  }

更好的解决方案,因为我无论如何都要创建new Settings(),可能是将此逻辑移动到Settings类方法并在构造函数中调用它

答案 2 :(得分:0)

尝试一下:let copy = original.map(item => Object.assign({}, ...item)); 这将创建一个新对象,而无需引用旧对象original

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

let copy = original.map(item => Object.assign([], ...item));

答案 3 :(得分:0)

最近我遇到了同样的问题,我无法弄清楚为什么我的某些对象更改了它们的属性。我必须更改代码以避免变异。此处的一些答案有助于我以后理解,例如这篇很棒的文章:https://alistapart.com/article/why-mutation-can-be-scary/

我推荐。作者提供了许多示例和有用的库,它们在嵌入属性方面的表现要优于Object.assign()