最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Can someone explain me this javascript object "copy" behavior - Stack Overflow

programmeradmin3浏览0评论

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: /

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/WSgVz/

Share Improve this question edited Jul 6, 2011 at 19:25 Lightness Races in Orbit 386k77 gold badges666 silver badges1.1k bronze badges asked Jul 6, 2011 at 19:23 BjörnBjörn 13.2k12 gold badges55 silver badges70 bronze badges 1
  • 5 Excellently-formed question and testcase. It's incredibly sad that this is so rare nowadays. – Lightness Races in Orbit Commented Jul 6, 2011 at 19:26
Add a ment  | 

5 Answers 5

Reset to default 5

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);
发布评论

评论列表(0)

  1. 暂无评论