问题
Can anyone explain why the obj
returns {a:2}
instead of {a:1}
in this case?
var obj = {a:1};
var data = {b:obj};
data.b.a = 2;
console.log(obj); // {a:2}
回答1:
objects in javascript are by reference, so when you change one reference you changed them. The meaning of this is you just created a shallow copy, you need to do a deep clone.
Deep copy can be made with jQuery this way:
// Deep copy
var newObject = jQuery.extend(true, {}, obj);
Read this why I used jQuery:
What is the most efficient way to deep clone an object in JavaScript?
(It's John Resig here on Stackoverflow...)
回答2:
In this case you're not cloning objects but rather setting additional references to the same variable. data.obj.a and obj.a point to the exact same memory location. Line 3 sets this memory value to 2.
To do a deep clone, try this:
var data = JSON.parse(JSON.stringify(obj));
回答3:
if using an NS derived browser like FF:
var data = { b: eval ( obj . toSource ( ) ) } ;
or
var data = { b: eval ( uneval ( obj ) ) } ;
if not:
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 ( ) } ;
There are many, many, many attempts posted in SO to do deepClone as well as
The structured clone algorithm - Web developer guide | MDN
hint: The Emperor has No Clothes
来源:https://stackoverflow.com/questions/14417645/javascript-object-cloning