将变量的值复制到另一个变量中

2022-08-30 05:35:49

我有一个变量,它有一个JSON对象作为其值。我直接将此变量分配给其他变量,以便它们共享相同的值。这是它的工作原理:

var a = $('#some_hidden_var').val(),
    b = a;

这有效,并且两者具有相同的值。我使用事件处理程序来更新我的应用。单击按钮时,我想恢复到原始值,即存储在 中的值。mousemovebba

$('#revert').on('click', function(e){
    b = a;
});

在此之后,如果我使用相同的事件处理程序,它将同时更新和,而之前它仅按预期更新。mousemoveabb

我在这个问题上很困惑!这是怎么回事?


答案 1

重要的是要了解JavaScript中的运算符做什么和不做什么。=

= 运算符不创建数据的副本

= 运算符创建对相同数据的新引用

运行原始代码后:

var a = $('#some_hidden_var').val(),
    b = a;

a并且现在是同一对象的两个不同名称。b

无论通过变量还是变量引用此对象,对此对象的内容所做的任何更改都将以相同的方式显示。它们是同一个对象。ab

因此,当您稍后尝试使用此代码“还原”到原始对象时:ba

b = a;

代码实际上根本不做任何事情,因为和是完全一回事。代码与您编写的代码相同:ab

b = b;

这显然不会做任何事情。

为什么你的新代码可以工作?

b = { key1: a.key1, key2: a.key2 };

在这里,您将创建一个具有对象文本的全新对象。此新对象与旧对象不同。因此,您现在正在设置为对此新对象的引用,该对象执行所需的操作。{...}b

要处理任何任意对象,您可以使用对象克隆函数,例如Armand的答案中列出的函数,或者由于您正在使用jQuery,因此只需使用$.extend()函数。此函数将创建对象的浅副本或深层副本。(不要将其与 $().clone() 方法混淆,后者用于复制 DOM 元素,而不是对象。

对于浅副本:

b = $.extend( {}, a );

或深度副本:

b = $.extend( true, {}, a );

浅拷贝和深度拷贝有什么区别?浅副本类似于创建具有对象文本的新对象的代码。它将创建一个新的顶级对象,其中包含对与原始对象相同的属性的引用。

如果您的对象仅包含数字和字符串等基元类型,则深层副本和浅副本将执行完全相同的操作。但是,如果您的对象包含嵌套在其中的其他对象或数组,则浅副本不会复制这些嵌套对象,而只是创建对它们的引用。因此,嵌套对象的问题可能与顶级对象的问题相同。例如,给定此对象:

var obj = {
    w: 123,
    x: {
        y: 456,
        z: 789
    }
};

如果对该对象执行浅层复制,则新对象的属性与原始对象的属性相同:xx

var copy = $.extend( {}, obj );
copy.w = 321;
copy.x.y = 654;

现在,您的对象将如下所示:

// 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.x.yobj.x.y

简短的回答:如果有疑问,你可能想要一个深度副本。


答案 2

我发现使用JSON工作,但观看我们的循环引用

var newInstance = JSON.parse(JSON.stringify(firstInstance));