Rut*_*rde 78 javascript jquery
我有一个变量,它有一个JSON对象作为其值.我直接将此变量分配给其他变量,以便它们共享相同的值.这是它的工作原理:
var a = $('#some_hidden_var').val(),
b = a;
Run Code Online (Sandbox Code Playgroud)
这有效,两者都有相同的价值.我使用mousemove事件处理程序来更新b我的应用程序.单击按钮,我想恢复b原始值,即存储的值a.
$('#revert').on('click', function(e){
b = a;
});
Run Code Online (Sandbox Code Playgroud)
在此之后,如果我使用相同的mousemove事件处理程序,它会同时更新两者,a并且b在更早时它仅b按预期更新.
我很难过这个问题!这有什么不对?
Mic*_*ary 178
了解=JavaScript中的运算符执行和不执行的操作非常重要.
该=运营商不会使拷贝数据.
在=操作创建一个新的参考到相同的数据.
运行原始代码后:
var a = $('#some_hidden_var').val(),
b = a;
Run Code Online (Sandbox Code Playgroud)
a而b现在为两个不同的名称相同的对象.
无论是通过a变量还是b变量引用,对此对象内容所做的任何更改都将完全相同.它们是同一个对象.
因此,当您稍后尝试使用此代码"恢复" b到原始a对象时:
b = a;
Run Code Online (Sandbox Code Playgroud)
代码实际上什么都不做,因为a并且b完全相同.代码与您编写的代码相同:
b = b;
Run Code Online (Sandbox Code Playgroud)
这显然不会做任何事情.
为什么新代码有效?
b = { key1: a.key1, key2: a.key2 };
Run Code Online (Sandbox Code Playgroud)
在这里,您将使用{...}对象文字创建一个全新的对象.这个新对象与旧对象不同.所以你现在设置b为这个新对象的引用,它可以满足您的需求.
要处理任何任意对象,您可以使用对象克隆功能,例如Armand的答案中列出的功能,或者因为您使用jQuery只需使用该$.extend()功能.此函数将生成对象的浅拷贝或深拷贝.(不要将此与用于复制DOM元素的$().clone()方法混淆,而不是复制对象.)
对于浅拷贝:
b = $.extend( {}, a );
Run Code Online (Sandbox Code Playgroud)
或深刻的副本:
b = $.extend( true, {}, a );
Run Code Online (Sandbox Code Playgroud)
浅拷贝和深拷贝之间有什么区别?浅拷贝类似于您创建具有对象文字的新对象的代码.它创建一个新的顶级对象,其中包含与原始对象相同属性的引用.
如果您的对象仅包含数字和字符串等基本类型,则深层副本和浅层副本将完全相同.但是如果你的对象包含嵌套在其中的其他对象或数组,那么浅拷贝不会复制那些嵌套对象,它只会创建对它们的引用.因此,您对顶级对象的嵌套对象可能会遇到同样的问题.例如,给定此对象:
var obj = {
w: 123,
x: {
y: 456,
z: 789
}
};
Run Code Online (Sandbox Code Playgroud)
如果您执行该对象的浅表副本,则x新对象的属性x与原始对象的属性相同:
var copy = $.extend( {}, obj );
copy.w = 321;
copy.x.y = 654;
Run Code Online (Sandbox Code Playgroud)
现在你的对象看起来像这样:
// 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
}
};
Run Code Online (Sandbox Code Playgroud)
您可以使用深层复制来避免这种情况.深拷贝会递归到每个嵌套对象和数组(以及Armand代码中的Date),以便像制作顶级对象的副本一样复制这些对象.所以改变copy.x.y不会影响obj.x.y.
简短回答:如果有疑问,您可能需要深层复制.
ker*_*ode 49
我发现使用JSON作品,但看我们的循环引用
var newInstance = JSON.parse(JSON.stringify(firstInstance));
Run Code Online (Sandbox Code Playgroud)
mar*_*osh 23
这个问题已经解决了很长时间,但为了将来的参考,可能的解决方案是
b = a.slice(0);
Run Code Online (Sandbox Code Playgroud)
请注意,只有当a是非嵌套的数字和字符串数组时,这才能正常工作
Arm*_*and 14
这样做的原因是简单的.JavaScript使用b = a引用,因此当您分配时,您正在分配引用,b因此在更新时a您也在更新b
我在stackoverflow上找到了这个,如果你想对对象进行深层复制,只需调用这个方法就可以防止将来这样的事情发生.
function clone(obj) {
// Handle the 3 simple types, and null or undefined
if (null == obj || "object" != typeof obj) return obj;
// Handle Date
if (obj instanceof Date) {
var copy = new Date();
copy.setTime(obj.getTime());
return copy;
}
// Handle Array
if (obj instanceof Array) {
var copy = [];
for (var i = 0, len = obj.length; i < len; i++) {
copy[i] = clone(obj[i]);
}
return copy;
}
// Handle Object
if (obj instanceof Object) {
var copy = {};
for (var attr in obj) {
if (obj.hasOwnProperty(attr)) copy[attr] = clone(obj[attr]);
}
return copy;
}
throw new Error("Unable to copy obj! Its type isn't supported.");
}
Run Code Online (Sandbox Code Playgroud)
Kis*_*til 11
newVariable = originalVariable.valueOf();
对于可以使用的对象,b = Object.assign({},a);
我不明白为什么答案如此复杂.在Javascript中,原语(字符串,数字等)按值传递并复制.对象(包括数组)通过引用传递.在任何情况下,为'a'分配新值或对象引用都不会改变'b'.但改变'a'的内容将改变'b'的内容.
var a = 'a'; var b = a; a = 'c'; // b === 'a'
var a = {a:'a'}; var b = a; a = {c:'c'}; // b === {a:'a'} and a = {c:'c'}
var a = {a:'a'}; var b = a; a.a = 'c'; // b.a === 'c' and a.a === 'c'
Run Code Online (Sandbox Code Playgroud)
将任何上述行(一次一个)粘贴到节点或任何浏览器javascript控制台中.然后键入任何变量,控制台将显示它的值.
| 归档时间: |
|
| 查看次数: |
168347 次 |
| 最近记录: |