2015-12-29 6 views
15

Я просто наткнулся на эту концепциюJS: Есть ли Object.assign() создает глубокую копию или неполную копию

var copy = Object.assign({}, originalObject); 

, который создает копию исходного объекта в «copy» объекта. Однако, мой вопрос заключается в том, создает ли этот способ клонирования объект глубокой копии или мелкой копии?

PS: Путаница, если она создает глубокую копию, тогда это был бы самый простой способ клонирования объекта.

+0

док сам за себя я думаю: «Метод Object.assign() используется для копирования значения всех ** перечислимых собственного ** свойств из одного или нескольких объектов источника к целевому объекту» – Sebas

ответ

18

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

MDN:

Метод

Object.assign() копирует только перечислимыми и собственные свойства от исходного объекта к целевому объекту

принять этот пример

var o = {}; 

Object.defineProperty(o,'x',{enumerable: false,value : 15}); 

var ob={}; 
Object.assign(ob,o); 

console.log(o.x); // 15 
console.log(ob.x); // undefined 
11

Используя Object.assign(), вы на самом деле делаете Shallow Copy вашего объекта. Всякий раз, когда мы выполняем операцию, такую ​​как присвоение одного объекта другому, мы фактически выполняем мелкую копию, то есть если OBJ1 является объектом, модифицируя его через другой объект, который OBJ2 будет также отражать изменения в OBJ1.

+15

если он делает только мелкую копию, как работает Redux? Я думал, что все дело в том, чтобы сделать глубокую копию данных, которые отправляются так, что если данные будут изменены за пределами магазина, это не изменит то, что находится в магазине. если бы это была мелкая копия, тогда данные были бы связаны, что вызывает проблемы с изменением данных, что находится в магазине, даже без отправки, правильно? – stackjlei

+0

Я столкнулся с этой проблемой в Redux, и в итоге я отправился в JSON.parse (JSON.stringify()). Это также имеет проблемы, если объект мутирован другим пакетом и создает рекурсивные проблемы. Я ищу лучшую альтернативу. Этот метод все еще тот, который я использую. – Stu

3

Это создает неполную копию, в соответствии с this paragraph from MDN:

Для глубокого клонирования, мы должны использовать другие альтернативы, потому что Object.assign() копирует значения свойств. Если исходное значение является ссылкой на объект , оно копирует только это ссылочное значение.

Для целей сокращения достаточно Object.assign(), поскольку состояние приложения redux содержит только неизменяемые значения (JSON).

+4

Не может ли состояние редукции приложения содержать объекты со ссылками на другие объекты ..? –

0

Для небольших Data structures Я вижу, что JSON.stringify() и JSON.parse() Работает хорошо.

// store as JSON 
var copyOfWindowLocation = JSON.stringify(window.location) 
console.log("JSON structure - copy:", copyOfWindowLocation) 
// convert back to Javascript Object 
copyOfWindowLocation = JSON.parse(copyOfWindowLocation) 
console.log("Javascript structure - copy:", copyOfWindowLocation)