将变量的值复制到另一个变量中 [英] Copy a variable's value into another
问题描述
我有一个变量,它有一个JSON对象作为其值。我直接将此变量分配给其他变量,以便它们共享相同的值。这是它的工作原理:
I have a variable which has a JSON object as its value. I directly assign this variable to some other variable so that they share the same value. This is how it works:
var a = $('#some_hidden_var').val(),
b = a;
这样做有效,两者都有相同的值。我使用 mousemove
事件处理程序通过我的应用程序更新 b
。单击按钮,我想将 b
恢复为原始值,这意味着该值存储在 a
中。
This works and both have the same value. I use a mousemove
event handler to update b
through out my app. On a button click, I want to revert b
to the original value, meaning the value stored in a
.
$('#revert').on('click', function(e){
b = a;
});
之后如果我使用相同的 mousemove
事件处理程序,它更新 a
和 b
,如果之前仅更新 b
如预期的那样。
After this if I use the same mousemove
event handler, it updates both a
and b
, when earlier it was updating only b
as expected.
我对此问题感到困惑!这里有什么问题?
I'm stumped over this issue! What is wrong here?
推荐答案
了解 =
的重要性JavaScript中的运算符有没有。
It's important to understand what the =
operator in JavaScript does and does not do.
=
运算符不会生成复制数据。
The =
operator does not make a copy of the data.
=
运算符创建一个新的引用到相同的数据。
The =
operator creates a new reference to the same data.
运行原始代码后:
var a = $('#some_hidden_var').val(),
b = a;
a
和 b
现在是同一个对象的两个不同名称。
您对此对象的内容所做的任何更改将通过 a
变量或 b
变量引用它。它们是相同的对象。
Any change you make to the contents of this object will be seen identically whether you reference it through the a
variable or the b
variable. They are the same object.
因此,当您稍后尝试将code> b 还原为原始<$使用以下代码的c $ c> a 对象:
So, when you later try to "revert" b
to the original a
object with this code:
b = a;
代码实际上什么都没有,因为 a
和 b
完全相同。代码与您写的相同:
The code actually does nothing at all, because a
and b
are the exact same thing. The code is the same as if you'd written:
b = b;
显然不会做任何事情。
为什么你的新代码有效?
Why does your new code work?
b = { key1: a.key1, key2: a.key2 };
在这里,您将使用 {...}创建一个全新的对象
object literal。这个新对象与旧对象不同。所以你现在设置 b
作为对这个新对象的引用,它可以做你想要的。
Here you are creating a brand new object with the {...}
object literal. This new object is not the same as your old object. So you are now setting b
as a reference to this new object, which does what you want.
要处理任何任意对象,你可以使用对象克隆函数,如Armand的答案中列出的那个,或者因为你正在使用jQuery,只需使用 $ .extend()
功能。此函数将生成对象的浅拷贝或深拷贝。 (不要将此与 $()混淆.clone()
方法,用于复制DOM元素,而不是对象。)
To handle any arbitrary object, you can use an object cloning function such as the one listed in Armand's answer, or since you're using jQuery just use the $.extend()
function. This function will make either a shallow copy or a deep copy of an object. (Don't confuse this with the $().clone()
method which is for copying DOM elements, not objects.)
对于浅层副本:
b = $.extend( {}, a );
或深拷贝:
b = $.extend( true, {}, a );
浅拷贝和深拷贝有什么区别?浅拷贝类似于您创建具有对象文字的新对象的代码。它创建了一个新的顶级对象,其中包含与原始对象相同属性的引用。
What's the difference between a shallow copy and a deep copy? A shallow copy is similar to your code that creates a new object with an object literal. It creates a new top-level object containing references to the same properties as the original object.
如果您的对象只包含数字和字符串等基本类型,则需要深层复制和浅拷贝会做同样的事情。但是如果你的对象包含嵌套在其中的其他对象或数组,那么浅拷贝不会复制那些嵌套对象,它只会创建对它们的引用。因此,您对顶级对象的嵌套对象可能会遇到同样的问题。例如,给定此对象:
If your object contains only primitive types like numbers and strings, a deep copy and shallow copy will do exactly the same thing. But if your object contains other objects or arrays nested inside it, then a shallow copy doesn't copy those nested objects, it merely creates references to them. So you could have the same problem with nested objects that you had with your top-level object. For example, given this object:
var obj = {
w: 123,
x: {
y: 456,
z: 789
}
};
如果您执行该对象的浅表副本,则 x 新对象的code>属性与原始对象的
x
对象相同:
If you do a shallow copy of that object, then the x
property of your new object is the same x
object from the original:
var copy = $.extend( {}, obj );
copy.w = 321;
copy.x.y = 654;
现在您的对象将如下所示:
Now your objects will look like this:
// copy looks as expected
var copy = {
w: 321,
x: {
y: 654,
z: 789
}
};
// But changing copy.x.y also changed obj.x.y!
var obj = {
w: 123, // changing copy.w didn't affect obj.w
x: {
y: 654, // changing copy.x.y also changed obj.x.y
z: 789
}
};
您可以使用深层复制来避免这种情况。深拷贝会递归到每个嵌套对象和数组(以及Armand代码中的Date),以便像制作顶级对象的副本一样复制这些对象。所以更改 copy.xy
不会影响 obj.xy
。
You can avoid this with a deep copy. The deep copy recurses into every nested object and array (and Date in Armand's code) to make copies of those objects in the same way it made a copy of the top-level object. So changing copy.x.y
wouldn't affect obj.x.y
.
简短回答:如果有疑问,您可能需要深层复制。
Short answer: If in doubt, you probably want a deep copy.
这篇关于将变量的值复制到另一个变量中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!