Ниже приведен пример сценария, который я воспользовался своей практикой этой проблемы. Если вы хотите перейти непосредственно к техническим деталям, см. «Технические детали» ниже.Когда необходимо использовать метод Object.assign() для копирования экземпляра объекта?
У меня есть персональный проект, над которым я изучаю JavaScript. В принципе, пользователь может создать ботинок, выбрав доступные опции.
Фокус в том, что левый и правый башмаки должны иметь одинаковый размер, среди прочих свойств, но такие вещи, как цвет, текстура шнурка обуви и т. Д., Могут быть независимыми свойствами для обуви. (Я полагал, что для меня это был достойный способ практиковать манипулирование объектами и наследование).
Пользователь начинает с проектирования правой обуви; когда нажата кнопка «своп», чтобы посмотреть на левый ботинок, пользователь в настоящее время видит копию правой обуви (но перевернутой). Только при первой замене обуви выровнялся левый ботинок и сделал точную копию правой обуви. С этого момента сохраняются уникальные варианты ориентации обуви. Затем, если пользователь вносит конкретные изменения в , то модель левого ботинка, а затем переключается на правый башмак, пользователь должен увидеть тот же самый правый ботинок, который они изначально разработали, прежде чем они нажали кнопку «своп» ,
Итак, если у их правой обуви были красные шнурки, они переключаются на левый ботинок и делают левый ботинок синим кружевом, а затем при переключении на правый ботинок пользователь должен видеть красные шнурки!
Технические детали
Когда я писал код для моего основного проекта я бегала в неприятность с уникальными вариантами, perserved. Например, если бы я сделал кружева зелеными для левой обуви, в правой обуви всегда были зеленые шнурки. Устранение неполадок, связанных с проблемой, было легким, потому что единственный раз, когда правый ботинок терял свои уникальные возможности, например, красное кружево, было, когда я установил цвет кружев для левой обуви.
console.log("THE RIGHT LACE BEFORE: " + rightShoe.laceId);
leftShoe.laceId = 'green';
console.log("THE RIGHT LACE AFTER: " + rightShoe.laceId);
Что бы войти в консоль была:
ПРАВО LACE ДО: красный
ПРАВО LACE ПОСЛЕ: зеленый
Несмотря на то, что я не изменял rightShoe
, он менялся всякий раз, когда я менял свойство leftShoe
.
Так что я вернулся туда, где я сначала определить leftShoe
объект, который, когда пользователь нажимает «своп» в первый раз в жизни сценария (Моя любительская мысль была почему размножать и заполнить leftShoe
объект, если пользователь, возможно, никогда не настраивает левый ботинок? Возможно, это излишне скупые данные, я не знаю). С тех пор, Я никогда не пересматривал leftShoe
как копию rightShoe
или наоборот. Я подумал, что меня подвешивает тот факт, что я, вероятно, делаю ссылку на объект, и, как и на других языках, я менял ссылку , а не значение.
Перед тем, как подойти к моим неприятностям, я хотел создать JSFiddle, чтобы воссоздать проблему. Поскольку мой проект длительный (около ~ 1500 строк, в том числе около THREE.js для графики), я сделал все возможное, чтобы подражать процессу. И так here it is.
За исключением того, что JSFiddle работал точно так, как я ожидал! Левая модель сохранила уникальный атрибут и данные, установленные для этого атрибута. Итак, я немного поработал и прочитал про Object.assign(). Так что в моем исходном коде проекта (не скрипкой), я изменил это:
leftShoe = rightShoe;
к этому:
leftShoe = Object.assign({}, rightShoe);
Как взволнован, так как я, чтобы наконец-то получил эту работу, я в равной степени удивлен и озадачен, потому что я не понимаю, почему мой JSFiddle не нуждался в методе assign()
, но мой идентичный код проекта. Спасибо.
В первом случае обе переменные ссылаются на один и тот же объект. Во втором случае вы создаете новый объект ('{}') и копируете все свойства с помощью 'Object.assign'. Мутирование одного объекта в другом не отразится. – Bergi
@ Bergi Спасибо, я думаю, что это имеет смысл для меня сейчас. Совместимость с другими языками. Но теперь меня бросает мой JSFiddle. Если вы посмотрите на мое ссылочное задание в строке 35 связанного Fiddle I, вы увидите, что значения для левой опции изменяются независимо от того, что это ссылочный объект. – 8protons
Ваша скрипка сбивает с толку (со всем этим currentChoice и leftChoiceExists), и, вероятно, вы смутили себя. После назначения вы можете видеть, что 'rightChoice.id' ==' leftChoice.id' - потому что обе переменные относятся к одному и тому же объекту. – Bergi