Björn
Björn

Reputation: 13207

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.log(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/

Upvotes: 6

Views: 313

Answers (5)

Domenic
Domenic

Reputation: 112817

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.

Upvotes: 5

Guffa
Guffa

Reputation: 700222

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 ({}).

Upvotes: 3

user578895
user578895

Reputation:

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);

Upvotes: 1

Cameron
Cameron

Reputation: 98746

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.

Upvotes: 1

sdleihssirhc
sdleihssirhc

Reputation: 42496

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.

Upvotes: 2

Related Questions