将变量的值复制到另一个变量中 [英] Copy a variable's value into another

查看:227
本文介绍了将变量的值复制到另一个变量中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个变量,它有一个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 属性与原始对象的 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆