Клонирование объектов JavaScript
Может кто-нибудь объяснить, почему obj
возвращается {a:2}
вместо {a:1}
в этом случае?
var obj = {a:1};
var data = {b:obj};
data.b.a = 2;
console.log(obj); // {a:2}
3 ответа
Объекты в javascript являются ссылочными, поэтому при изменении одной ссылки вы меняете их. Смысл этого в том, что вы только что создали неглубокую копию, вам нужно сделать глубокий клон.
Глубокое копирование может быть сделано с помощью jQuery следующим образом:
// Deep copy
var newObject = jQuery.extend(true, {}, obj);
Прочитайте, почему я использовал jQuery: Какой самый эффективный способ глубокого клонирования объекта в JavaScript?
(Это Джон Резиг здесь, на Stackru...)
В этом случае вы не клонируете объекты, а устанавливаете дополнительные ссылки на одну и ту же переменную. data.obj.a и obj.a указывают на одну и ту же область памяти. Строка 3 устанавливает это значение памяти в 2.
Чтобы сделать глубокий клон, попробуйте это:
var data = JSON.parse(JSON.stringify(obj));
Если вы используете браузер, полученный из NS, такой как FF:
var data = { b: eval ( obj . toSource ( ) ) } ;
или же
var data = { b: eval ( uneval ( obj ) ) } ;
если не:
Object . function . deepClone = function(){
/*
highly non-trivial to accommodate objects like:
animal=123; animal.beastly=432; ie. object "overloading"
monster = new ( function ( ) { this . this = this } ) ( ) ie. self-referential / recursive
Note: JSON cannot do these but toSource () can handle recursive structures
alert ( new ( function ( ) { this . this = this } ) ( ) . toSource ( ) );
ie. #1={this:#1#}
alert ( new ( function ( ) { this [ this ] = this } ) ( ) . toSource ( ) );
ie. #1={'[object Object]':#1#}
alert ( new ( function ( ) { this [ this . toSource ( ) ] = this } ) ( ) . toSource ( ) );
ie. #1={'({})':#1#}
alert ( ( #1 = { '({})' : #1# } ) . toSource ( ) );
ie. #1={'({})':#1#}
*/
}
var data = { b: obj . deepClone ( ) } ;
В SO опубликовано много, много, много попыток сделать deepClone, а также
Алгоритм структурированного клона - Руководство веб-разработчика | MDN
подсказка: у императора нет одежды