简体   繁体   English

谁能解释一下这个 javascript object “复制”行为

[英]Can someone explain me this javascript object “copy” behavior

I have the following code (I am using the jQquery libary):我有以下代码(我正在使用 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);

My Question: When I do obj.key = jsonobj and I change values in the new obj.key.我的问题:当我执行 obj.key = jsonobj 并更改新 obj.key 中的值时。 Why do values in jsonobj then also change?为什么 jsonobj 中的值也会发生变化? And how would I avoid that?我将如何避免这种情况? (I want a new "copy" of jsonobj). (我想要一个 jsonobj 的新“副本”)。

I made this test case: http://jsfiddle.net/WSgVz/我做了这个测试用例: 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:我想解决这里发生的一小部分,因为其他人已经很好地解决了 JavaScript object 参考文献的更大问题:

// 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.这是记录在案的 WebKit 错误的结果,即console.log语句在调用console.log时不是 output 和 object ,而是稍后一段时间。

That is because the object is not copied.那是因为没有复制 object。 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 . obj.key属性将仅包含对 object 的引用,因此当您将某些内容分配给obj.key.test时,效果与将其分配给jsonobj.test相同。

You can use the jQuery method extend to create a copy:您可以使用 jQuery 方法扩展创建副本:

obj.key = $.extend({}, jsonobj);

This will copy the values into the newly created object ( {} ).这会将值复制到新创建的 object ( {} ) 中。

Because when you do obj.key = jsonobj , there isn't some new, copied object in obj.key ;因为当您执行obj.key = jsonobj时,在 obj.key 中没有新的复制obj.key it's just a reference to the jsonobj that already exists.它只是对已经存在的jsonobj的引用。 So changes to obj.key will also change jsonobj , because they're actually the same thing.所以对obj.key的改变也会改变jsonobj ,因为它们实际上是一样的。

This is because there is no copying going on -- there is only one object, which is referenced by various variables and properties.因为没有进行复制——只有一个 object,它被各种变量和属性引用 When you do obj.key = jsonobj , you are merely copying the reference to the same object.当您执行obj.key = jsonobj时,您只是将引用复制到相同的 object。

All objects in JavaScript are copied by reference, meaning: JavaScript 中的所有对象都是通过引用复制的,意思是:

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.如果你想要obj.key != jsonobj ,你需要克隆 object。 By creating a new object:通过创建一个新的 object:

obj.key = $.parseJSON(objstring);

or using jQuery to clone the existing one:或使用 jQuery 克隆现有的:

obj.key = $.extend({}, jsonobj);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM