2016-04-19 2 views
11

Ниже приведен пример сценария, который я воспользовался своей практикой этой проблемы. Если вы хотите перейти непосредственно к техническим деталям, см. «Технические детали» ниже.Когда необходимо использовать метод 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(), но мой идентичный код проекта. Спасибо.

+0

В первом случае обе переменные ссылаются на один и тот же объект. Во втором случае вы создаете новый объект ('{}') и копируете все свойства с помощью 'Object.assign'. Мутирование одного объекта в другом не отразится. – Bergi

+0

@ Bergi Спасибо, я думаю, что это имеет смысл для меня сейчас. Совместимость с другими языками. Но теперь меня бросает мой JSFiddle. Если вы посмотрите на мое ссылочное задание в строке 35 связанного Fiddle I, вы увидите, что значения для левой опции изменяются независимо от того, что это ссылочный объект. – 8protons

+0

Ваша скрипка сбивает с толку (со всем этим currentChoice и leftChoiceExists), и, вероятно, вы смутили себя. После назначения вы можете видеть, что 'rightChoice.id' ==' leftChoice.id' - потому что обе переменные относятся к одному и тому же объекту. – Bergi

ответ

8

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

+1

Спасибо! Поэтому я должен спросить, почему это не так с моим JSFiddle, с которым я связан? Я использую ссылочное задание, но все же могу внести изменения. Проверьте строку 35 моего Fiddle, а затем пройдите через кнопки, которые я сделал, наблюдая за выходом. – 8protons

+0

Скрипка кажется разбитой для меня. rightId получает значение 444, когда он должен оставаться 999 –

Смежные вопросы