Свойства Object.assign () и Spread все еще изменяют оригинал - PullRequest
0 голосов
/ 25 апреля 2018

Я пытаюсь присвоить объекту значение элемента массива.После первой попытки что-то вроде, например, bar = foo[0];, я обнаружил, что любое изменение в bar также меняет foo[0], из-за наличия той же ссылки.

Удивительно, никто не подумал, и после прочтенияна неизменяемость и ES6 метод Object.assign () и распространение свойства, я думал, что это решит проблему.Однако в этом случае это не так.Чего мне не хватает?

РЕДАКТИРОВАТЬ: Извините за путаницу accountTypes , я исправил пример.Кроме того, я хотел бы сохранить структуру класса Настройки , так что let copy = JSON.parse(JSON.stringify(original)); не совсем то, что мне нужно в этом случае.

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

Ответы [ 3 ]

0 голосов
/ 25 апреля 2018

Это на самом деле не отвечает на вопрос, но поскольку объект, который я пытаюсь не изменять, не имеет вложенных свойств внутри, я вызываю присвоение на уровне свойств, и мелкая копия здесь подходит.

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 и вызвать ее в конструкторе

0 голосов
/ 02 октября 2018

Попробуйте это: let copy = original.map(item => Object.assign({}, ...item)); Это создаст новый объект без какой-либо ссылки на старый объект original

Если вы хотите сделать это для массива, попробуйте то же самое с []

let copy = original.map(item => Object.assign([], ...item));
0 голосов
/ 25 апреля 2018

Вы должны сделать глубокую копию, это самый простой способ:

let copy = JSON.parse(JSON.stringify(original));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...