Когда необходимо использовать метод Object.assign() для копирования экземпляра объекта?

Ниже приведен пример сценария, который я использовал для собственной практики этой проблемы. Если вы хотите перейти к техническим деталям, см. "Технические детали" ниже.

У меня есть личный проект, над которым я работал, чтобы изучить JavaScript. В принципе, пользователь может создать ботинок, выбрав доступные варианты.

Фокус в том, что левый и правый башмаки должны иметь одинаковый размер, среди других свойств, но такие вещи, как цвет, текстура шнурка обуви и т.д., могут быть независимыми свойствами для обуви. (Я полагал, что для меня это был достойный способ практиковать манипуляции с объектами и наследование).

Пользователь начинает с проектирования правой обуви; когда нажата кнопка "своп", чтобы посмотреть на левый ботинок, пользователь в настоящее время видит копию правой обуви (но перевернутой). Только при первой замене обуви выровнялся левый ботинок и сделал точную копию правой обуви. С этого момента сохраняются уникальные опции на ориентацию обуви. Затем, если пользователь вносит конкретные изменения в эту модель с левым ботинком, а затем переключается на правый ботинок, пользователь должен увидеть тот же самый правый ботинок что они изначально были разработаны до того, как они нажали кнопку "своп".

Итак, если у их правой обуви были красные шнурки, они переключаются на левый ботинок и делают левый ботинок синим кружевом, тогда при переключении обратно в правую обувь пользователь должен видеть красные шнурки!


Технические данные

Когда я писал код для моего основного проекта, у меня возникали проблемы с сохранением уникальных параметров. Например, если бы я сделал кружева зелеными для левой обуви, в правой обуви всегда были зеленые шнурки. Устранение неполадок, связанных с проблемой, было легко, потому что единственный раз, когда правый ботинок терял уникальные параметры, такие как красное кружево, было, когда я установил цвет кружев для левой обуви.

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

Что нужно для входа в консоль:

ПРАВИЛЬНЫЙ ЛИЦ ДО: красный

ПРАВАЯ ЛИЦА ПОСЛЕ: зеленый

Даже если я не менял rightShoe, он менялся всякий раз, когда я менял свойство leftShoe.

Итак, я вернулся к тому, где я сначала определяю объект leftShoe, когда пользователь щелкает "swap" в первый раз в жизни script (Моя любительская мысль была причиной распространения и заполнения leftShoe object, если пользователь, возможно, никогда не настраивает левый ботинок? Возможно, это излишне скупые данные, я не знаю). С тех пор я никогда не переопределял leftShoe как копию rightShoe или наоборот. Я подумал, что меня подвешивает тот факт, что я, вероятно, делаю ссылку на объект, и, как и на других языках, я менял ссылку, а не значение.

Прежде чем приступить к SO с моими проблемами, я хотел создать JSFiddle, чтобы воссоздать проблему. Поскольку мой проект длинный (около ~ 1500 строк, в том числе THREE.js для графики), я сделал все возможное, чтобы подражать процессу. И поэтому здесь это.

За исключением того, что JSFiddle работал точно так, как я ожидал! Левая модель сохранила уникальный атрибут и данные, установленные для этого атрибута. Итак, я немного поработал и прочитал о методе Object.assign(). Поэтому в моем исходном коде проекта (а не скрипке) я изменил это:

leftShoe = rightShoe;

:

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

Взволнованный, как я должен, наконец, заставить это работать, я также удивлен и озадачен, потому что я не понимаю, почему мой JSFiddle не нуждался в методе assign(), но мой идентичный код проекта. Спасибо.

Ответ 1

Object.Assign делает новую КОПИЮ левой обуви, включая все перечислимые СОБСТВЕННЫЕ свойства. Когда вы используете leftshoe = rightshoe, вы делаете ссылку на левый ботинок. Ссылка указывает на тот же объект, а не на НОВУЮ КОПИЮ. Таким образом, изменение свойства ссылки фактически изменяет оригинал, как вы отметили.