我有以下代码(我正在使用jQquery库):
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);
我的问题: 当我做obj.key = jsonobj并且我在新的obj.key中更改值。为什么jsonobj中的值也会改变?我怎么能避免这种情况? (我想要一个jsonobj的新“副本”。
我做了这个测试用例:http://jsfiddle.net/WSgVz/
答案 0 :(得分:5)
我想解决这里发生的一小部分问题,因为其他人已经很好地解决了JavaScript对象引用的大问题:
// second console output
console.log(jsonobj);
obj.key = jsonobj;
obj.key.test = "why does this affect jsonobj? (even in the second console output)";
这是documented WebKit bug的结果,console.log
语句在调用console.log
时不输出对象,而是在一段时间之后输出。
答案 1 :(得分:3)
这是因为没有复制对象。 obj.key
属性只包含对象的引用,因此当您为obj.key.test
分配内容时,效果与将其分配给jsonobj.test
相同。
您可以使用jQuery方法extend创建副本:
obj.key = $.extend({}, jsonobj);
这会将值复制到新创建的对象({}
)。
答案 2 :(得分:2)
因为当您执行obj.key = jsonobj
时,obj.key
中没有新的复制对象;它只是对已存在的jsonobj
的引用。因此,对obj.key
的更改也会更改jsonobj
,因为它们实际上是相同的。
答案 3 :(得分:1)
这是因为 没有进行复制 - 只有一个对象,referenced由各种变量和属性组成。执行obj.key = jsonobj
时,您只是将引用复制到同一对象。
答案 4 :(得分:1)
JavaScript中的所有对象都是通过引用复制的,这意味着:
var x = {};
var y = x;
x.foo = 22; // y.foo also = 22 since y and x are the same object
如果您需要obj.key != jsonobj
,则需要克隆该对象。通过创建一个新对象:
obj.key = $.parseJSON(objstring);
或使用jQuery克隆现有的:
obj.key = $.extend({}, jsonobj);