为什么 Javascript 对象引用没有更新?

Why is Javascript object reference not updated?

我正在创建一堆对象,我想在其他对象中使用其中的一些对象,所以我将它们传递进来,以便稍后更新它们。我希望保留对每个对象的引用,但如果我在对象创建之前传递它,即使在我创建它之后它仍保持未定义状态。这是代码:

this.screen = new BatchScreen(screenList);
this.fieldData = new FieldData(this.screen, this.nutrientData);
this.nutrientData = new NutrientData(this.screen, this.fieldData);

function FieldData(screen, nutrientData)
{
    this.nutrientData = nutrientData;
}

this.fieldData.nutrientData 是 "undefined",我不明白,因为我认为 this.fieldData 持有对 this.nutrientData 的引用,这是我在 [=] 中分配后创建的18=].

简短:您没有传递引用。

Long:JS中的求值策略是Call by sharing。它也被解释为 "references passed by values".

详细的意思是-在你的

this.fieldData = new FieldData(this.screen, this.nutrientData);

声明 this.screen 持有一个引用,因此它是按值传递的。 this.nutrientData 没有任何内容 - 所以 undefined 被传递了。

那么当你 运行

this.nutrientData = new NutrientData(this.screen, this.fieldData);

声明 this.nutrientData 被定义为对新对象的引用。但为时已晚 - 我们已经在 FieldData 构造函数中传递了 undefined

所以最好的理解方式 - 始终认为数据总是按值传递,但有时这些值保留引用。

为了让您的代码按预期工作,self.nutrientData 和其他必须是指针,JS 不以任何方式支持它们。

解决方法:

如果你有 2 个相互依赖的对象,那么你不能在它们自己的构造函数中同时拥有这两个对象。其中之一只需要公开额外的 setter 并通过它接受依赖项。

在这种情况下,第二行的 this.nutrientData 没有作为引用传递,因为不存在对对象的引用(此时不存在 this.nutrientData,因此您是从字面上传递 undefined).

我猜你也遇到了 this;

的范围问题

试试这个(没有双关语意):

var self = this;
this.screen = new BatchScreen(screenList);
this.fieldData = new FieldData(self.screen, new NutrientData(self.screen, self.fieldData));
// assumes that the nutrientData property exists from the object passed into FieldData
this.nutrientData = this.fieldData.nutrientData;
function FieldData(screen, nutrientData)
{
    this.nutrientData = nutrientData;
}

不是答案,而是可能的解决方案。您确实需要 getter,但支持还不够广泛。如果你有相互依赖的属性,你可以实现一个 getter 为一个(或者可能为一致性)所以你有:

this.screen = new BatchScreen(screenList);

// Don't bother passing this.nutrientData since you know it's not defined yet,
// pass in the object that you want the nutrientData property of
this.fieldData = new FieldData(this.screen, this);
this.nutrientData = new NutrientData(this.screen, this.fieldData);

// In here, use a function to return the property so its read when called, 
// not when defined
function FieldData(screen, obj) {
    this.getNutrientData = function () {return obj.nutrientData};
}

然后代替:

var foo = someInstance.fieldData.nutrientData;

使用:

var foo = someInstance.fieldData.getNutrientData();

但是fieldDatanutrientData之间似乎存在循环关系。