我有一个变量,它的值是JSON对象.我直接把这个变量分配给其他变量,这样它们就可以共享相同的值.这就是它的工作原理:

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

这是可行的,两者都有相同的价值.我使用mousemove事件处理程序在我的应用程序中更新b.点击一个按钮,我想将b恢复为原始值,即存储在a中的值.

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

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中的=运算符做什么和不做什么很重要.

The = operator does not make a copy of the data.

The 100 operator creates a new reference to the same data.

After you run your original code:

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

ab现在是the same object的两个不同名称.

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.

So, when you later try to "revert" b to the original a object with this code:

b = a;

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;

which obviously won't do anything.

Why does your new code work?

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

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.

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.)

For a shallow copy:

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属性相同:

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代码中的日期),以复制这些对象,其方式与复制顶级对象的方式相同.所以更改copy.x.y不会影响obj.x.y.

Short answer: If in doubt, you probably want a deep copy.

Jquery相关问答推荐

ASP.NET Core 8 MVC:从jQuery发布控制器中的所有值为空

使用 howler.js 中的变量播放多种声音

多个 AJAX 调用;获取所有失败的呼叫

jQueryUI 模态对话框不显示关闭按钮 (x)

Jquery each - 停止循环并返回对象

如何使用 jquery 获取屏幕的高度

如何使用 jQuery 搜索 JSON 树

为什么 jquery fadeIn() 不能与 .html() 一起使用?

不使用插件的 jQuery 缓动函数

jQuery .get 错误响应函数?

如何使用 Twitter Bootstrap 弹出框进行 jQuery 验证通知?

即使通过Javascript代码判断,如何触发复选框单击事件?

如何从表格单元格 (td) 中获取相应的表格标题 (th)?

如何使用jQuery在弹出窗口中预览输入类型=文件中的选定图像?

如何在 Angular 4 中使用 jQuery 插件?

获取跨域 iframe 的 DOM 内容

类方法中的Typescript this

使用 jQuery 获取鼠标单击图像的 X/Y 坐标

在某个点停止固定位置滚动?

使用 jQuery 和 CSS 将数字转换为星级显示