了解=
JavaScript 中的运算符做什么和不做什么很重要。
=
操作员不会复制数据。
=
操作员创建对相同数据的新引用。
运行原始代码后:
var a = $('#some_hidden_var').val(),
b = a;
a
现在是同一个对象的b
两个不同名称。
a
无论您是通过变量还是通过变量引用它,您对这个对象的内容所做的任何更改都将被相同地看到b
。它们是同一个对象。
因此,当您稍后尝试使用此代码“恢复”b
到原始a
对象时:
b = a;
代码实际上什么都不做,因为a
和b
是完全相同的东西。代码与您编写的代码相同:
b = b;
这显然不会做任何事情。
为什么您的新代码有效?
b = { key1: a.key1, key2: a.key2 };
{...}
在这里,您正在使用对象文字创建一个全新的对象。这个新对象与您的旧对象不同。因此,您现在设置b
为对这个新对象的引用,它可以执行您想要的操作。
要处理任意对象,您可以使用对象克隆功能,例如 Armand 的答案中列出的功能,或者由于您使用的是 jQuery,因此只需使用该$.extend()
功能。此函数将对对象进行浅拷贝或深拷贝。(不要将此与用于复制 DOM 元素而非对象的$().clone()
方法混淆。)
对于浅拷贝:
b = $.extend( {}, a );
或深拷贝:
b = $.extend( true, {}, a );
浅拷贝和深拷贝有什么区别?浅拷贝类似于使用对象文字创建新对象的代码。它创建一个新的顶级对象,其中包含对与原始对象相同的属性的引用。
如果你的对象只包含像数字和字符串这样的原始类型,那么深拷贝和浅拷贝会做同样的事情。但是,如果您的对象包含嵌套在其中的其他对象或数组,那么浅拷贝不会复制这些嵌套对象,它只会创建对它们的引用。因此,嵌套对象可能会遇到与顶级对象相同的问题。例如,给定这个对象:
var obj = {
w: 123,
x: {
y: 456,
z: 789
}
};
如果您对该对象进行浅拷贝,则x
新对象的属性x
与原始对象相同:
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.y
不会影响obj.x.y
。
简短的回答:如果有疑问,您可能想要一个深层副本。