javascript持久化更改

javascript持久化更改,javascript,Javascript,我有一个由20个对象组成的数组BaseObjects,称为ArrayBaseObjects。 用户调用一个对象,将其加载到UI中,并对属性进行更改。 大概是这样的: var ArrayBaseObjects = new Array(); var CurrentObject = null; function OpenRecord (TheIndex) { CurrentObject = ArrayBaseObjects[TheIndex]; } function RecordChanges

我有一个由20个对象组成的数组BaseObjects,称为ArrayBaseObjects。 用户调用一个对象,将其加载到UI中,并对属性进行更改。 大概是这样的:

var ArrayBaseObjects = new Array();
var CurrentObject = null;

function OpenRecord (TheIndex) {
  CurrentObject = ArrayBaseObjects[TheIndex];
}

function RecordChanges() {
 // bunch of statements that make changes to CurrenObject
 CurrentObject.CrazyStuff = NewValue;
}
问题在于,当用户更改CurrentObject时,它也会更改ArrayBaseObjects中原始对象的值

我不明白为什么??当我写
CurrentObject=ArrayBaseObjects[TheIndex]为什么更改CurrentObject也会影响ArrayBaseObject中对象的值

我想比较用户更改的原始对象和当前对象之间的值,但它们总是相同的!我需要做什么样的改变才能让它按照我的意愿工作


感谢您的解释。

JavaScript中几乎所有内容都是通过引用传递的。这意味着,除非显式克隆对象,否则将对象指定给新变量意味着现在有两个变量指向同一对象,并且通过一个变量对该对象所做的更改将从第二个变量可见

对于如何修复此问题的答案,您需要的是克隆对象。然而,这不一定是一件小事,以优雅的方式执行

幸运的是,JavaScript忍者已经完成了艰苦的工作。我建议使用,这是一种很好的方法,你可以指定它来做一个测试。这可以确保对象中的所有数据都被克隆,而不仅仅是顶级引用

有关更多信息,请参阅

在您的情况下,您可以这样使用它:

var ArrayBaseObjects = [];
var CurrentObject = {};

function OpenRecord (TheIndex) {
  // This will perform a deep copy of all elements of the ArrayBaseObjects[TheIndex]
  // into CurrentObject
  jQuery.extend(true, CurrentObject, ArrayBaseObjects[TheIndex]);
  // You could also call it like this, if you didn't need the CurrentObject variable:
  // var clonedObject = jQuery.extend(true, {}, ArrayBaseObjects[TheIndex]);
}

function RecordChanges() {
 // bunch of statements that make changes to CurrenObject
 CurrentObject.CrazyStuff = NewValue;
}

原因是变量包含对对象的引用,而不是对象本身

声明

CurrentObject = ArrayBaseObjects[TheIndex];
使
CurrentObject
的值与
ArrayBaseObjects[TheIndex]
的值相同。这两个值都是指向同一对象的引用或指针。这里只有一个对象,尽管有两个变量。您可以通过任一变量更改此单个对象的属性,您将通过另一个变量“看到此更改”

这一切都归结为理解变量和对象之间的差异。在JavaScript中,使用多个变量引用一个对象是非常常见的。每当将对象指定给变量,或将对象作为参数传递给函数时,都会发生这种情况

下面是一个简单的测试:

var a = {x:1, y:2};
var b = a;
b.x = 5;
alert(a.x);  // 5
为什么?


一个对象,两个变量。

这是因为将ArrayBaseObjects[TheIndex]分配给CurrentObject就是分配一个引用。有关如何“克隆”对象的信息,请参见此处:


深度复制是指不仅复制对象的属性,而且如果其中任何属性本身就是对象,那么这些对象也会被深度复制。这是一个递归操作,但是要注意确保循环引用得到很好的处理。
              +---------+
a ----------> | x [ 5 ] |
              | y [ 2 ] |
              +---------+
                   ^
                   |
b -----------------+