Can someone explain me this javascript object "copy" behavior
I have the following code (I am using the jQquery libary):
var obj = {};
var objstring = '{"one":"one","two":"two","three":"three"}'
// first console output
console.log(objstring);
var jsonobj = $.parseJSON(objstring);
// second console output
console.l开发者_如何学运维og(jsonobj);
obj.key = jsonobj;
obj.key.test = "why does this affect jsonobj? (even in the second console output)";
// third console output
console.log(jsonobj);
My Question: When I do obj.key = jsonobj and I change values in the new obj.key. Why do values in jsonobj then also change? And how would I avoid that? (I want a new "copy" of jsonobj).
I made this test case: http://jsfiddle.net/WSgVz/
I want to address a small piece of what is going on here, since others have done so well addressing the larger issues of JavaScript object references:
// second console output
console.log(jsonobj);
obj.key = jsonobj;
obj.key.test = "why does this affect jsonobj? (even in the second console output)";
This is the result of a documented WebKit bug, that console.log
statements do not output the object at the time of calling console.log
, but instead some time later.
That is because the object is not copied. The obj.key
property will only contain a reference to the object, so when you assign something to obj.key.test
the effect is the same as assigning it to jsonobj.test
.
You can use the jQuery method extend to create a copy:
obj.key = $.extend({}, jsonobj);
This will copy the values into the newly created object ({}
).
Because when you do obj.key = jsonobj
, there isn't some new, copied object in obj.key
; it's just a reference to the jsonobj
that already exists. So changes to obj.key
will also change jsonobj
, because they're actually the same thing.
This is because there is no copying going on -- there is only one object, which is referenced by various variables and properties. When you do obj.key = jsonobj
, you are merely copying the reference to the same object.
All objects in JavaScript are copied by reference, meaning:
var x = {};
var y = x;
x.foo = 22; // y.foo also = 22 since y and x are the same object
If you want obj.key != jsonobj
, you need to clone the object. By creating a new object:
obj.key = $.parseJSON(objstring);
or using jQuery to clone the existing one:
obj.key = $.extend({}, jsonobj);
精彩评论