javascript - 如果我在构造函数中使用 for 循环,私有(private)变量不是特定于对象的 : JavaScript

标签 javascript prototype

我遇到了一个奇怪的问题,看看下面的代码..

var ApplicationParser = (function(){

ApplicationParser.prototype.messageFramer;
ApplicationParser.prototype.isPreviousFetchingDirection;
ApplicationParser.prototype.latestDataArrays = [];
ApplicationParser.prototype.dataPointsArray = [];
ApplicationParser.prototype.chartObject;
ApplicationParser.prototype.titleLabel;
ApplicationParser.prototype.chartConfiguration;
ApplicationParser.prototype.htmlId;

function ApplicationParser(url,dataPointArray, title, htmlId,fetchSize) {

    this.messageFramer = new MessageFramer(url,fetchSize);
    this.isPreviousFetchingDirection = true;
    this.messageFramer.FetchNextData(this,this.isPreviousFetchingDirection);

    this.dataPointsArray = dataPointArray;
    this.titleLabel = title;
    this.htmlId = htmlId;

    for (var int = 0; int < globalConfiguration.length; int++) {
        var array_element = globalConfiguration[int];
        this.latestDataArrays[array_element] = new Array();

    }
}
return ApplicationParser; }());
var app1 = new ApplicationParser('url',dataPointArray,title,"#context", 50000);

app1.latestDataArrays = [1,2,3];
app1.dataPointsArray = [1,2,3];

var app2 = new ApplicationParser('url',dataPointArray,title,"#context", 50000);

app2.latestDataArrays = [4,5,6];
app2.dataPointsArray  = [4,5,6];

现在,如果您尝试访问两个对象的“latestDataArrays”,那么它将显示 [4,5,6];而“dataPointsArray”仍然不同。为什么“latestDataArrays”也无法显示不同的值...

如果我用下面的代码替换上面的代码,那么问题就解决了......

var ApplicationParser = (function(){

ApplicationParser.prototype.messageFramer;
ApplicationParser.prototype.isPreviousFetchingDirection;
ApplicationParser.prototype.latestDataArrays = [];
ApplicationParser.prototype.dataPointsArray = [];
ApplicationParser.prototype.chartObject;
ApplicationParser.prototype.titleLabel;
ApplicationParser.prototype.chartConfiguration;
ApplicationParser.prototype.htmlId;

function ApplicationParser(url,dataPointArray, title, htmlId,fetchSize) {

    this.messageFramer = new MessageFramer(url,fetchSize);
    this.isPreviousFetchingDirection = true;
    this.messageFramer.FetchNextData(this,this.isPreviousFetchingDirection);

    this.dataPointsArray = dataPointArray;
    this.titleLabel = title;
    this.htmlId = htmlId;

    var latArrayTemp = new Object();

    for (var int = 0; int < globalConfiguration.length; int++) {
        var array_element = globalConfiguration[int];
        latArrayTemp[array_element] = new Array();

    }
    this.latestDataArrays = latArrayTemp;
}

return ApplicationParser;}());

请告诉其背后的原因是什么,是否是构造函数内的 for 循环创建问题,如果是,那么为什么......?

最佳答案

请问这背后的原因是什么,是构造函数内的for循环创建问题吗?

不,它与 for 循环无关。问题的根本原因是:

dataPointsArrayapp1app2 的实例变量——每个 ApplicationParser 对象都有自己唯一的dataPointsArray 实例。

但是,latestDataArraysApplicationParser.prototype 中的一个字段,这意味着所有 ApplicationParser 对象(app1app2)将共享 latestDataArrays 实例(除非他们声明它的 latestDataArrays 指向其他内容。这正是第二个代码片段的行为)。

如何解决问题?

由于 dataPointsArraylatestDataArrays 是实例变量,请将它们从 ApplicationParser.prototype 中删除。即删除以下两行:

ApplicationParser.prototype.latestDataArrays = [];
ApplicationParser.prototype.dataPointsArray = [];
<小时/>

一些详细说明:

代码中发生了什么:var app = new ApplicationParser(...)

当调用new ApplicationParser(...)时,执行以下步骤:

  1. 创建一个空对象并从 ApplicationParser.prototype 扩展。我们称之为 X。
  2. 执行函数 ApplicationParser(构造函数),在函数内使用 X 作为 this
  3. 如果构造函数内没有return语句,则返回X;
  4. 将 X 分配给应用

app1app2 会发生什么情况?

对于 var app1 = new ApplicationParser(...) 语句,我们将其“X”称为 Xapp1。

对于 var app2 = new ApplicationParser(...) 语句,我们将其“X”称为 Xapp2。

创建 Xapp1 后且在构造函数运行之前,Xapp1.dataPointsArray 指向 ApplicationParser.prototype.dataPointsArrayXapp1.latestDataArrays 点到ApplicationParser.prototype.latestDataArrays:

Xapp1.dataPointsArray === ApplicationParser.prototype.dataPointsArray // true
Xapp1.latestDataArrays === ApplicationParser.prototype.latestDataArrays // true

创建 Xapp1 并运行构造函数后,Xapp1.dataPointsArray 指向一个新对象(相应的参数,我们将其称为 D1)和 Xapp1.latestDataArrays > 仍然指向 ApplicationParser.prototype.latestDataArrays,因为它没有重新分配,this.latestDataArrays[array_element] = ... 仅更改对象的某些属性this.latestDataArrays 指向。

Xapp1.dataPointsArray === ApplicationParser.prototype.dataPointsArray // false, as Xapp1.dataPointsArray is D1 now.
Xapp1.latestDataArrays === ApplicationParser.prototype.latestDataArrays // true

对于Xapp2,逻辑是相同的,所以:

Xapp2.dataPointsArray === ApplicationParser.prototype.dataPointsArray // false, as Xapp2.dataPointsArray is D2 now.
Xapp2.latestDataArrays === ApplicationParser.prototype.latestDataArrays // true

因此,很明显,Xapp1 和 Xapp2 共享 latestDataArrays 对象,但它们的 dataPointsArray 是唯一的。

为什么第二个代码片段有效?

第二个代码片段之所以有效,是因为以下语句:

this.latestDataArrays = latArrayTemp;

此语句重新分配 latestDataArrays 字段,使 Xapp1 的 latestDataArrays 指向一个新对象(我们称之为 L1),而 Xapp2 的 latestDataArrays > 指向另一个(L2)。因此:

Xapp1.latestDataArrays === ApplicationParser.prototype.latestDataArrays // false, as Xapp1.latestDataArrays is L1 now.
Xapp2.latestDataArrays === ApplicationParser.prototype.latestDataArrays // false, as Xapp2.latestDataArrays is L2 now.

这使得 Xapp1 和 Xapp2 的 latestDataArrays 独一无二。

关于javascript - 如果我在构造函数中使用 for 循环,私有(private)变量不是特定于对象的 : JavaScript,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44796033/

相关文章:

javascript - JavaScript 中的 "dot function"运算符

javascript - 如何从 javascript 模块模式中的函数原型(prototype)访问私有(private)属性?

javascript - 如何获取特殊字符之前的子字符串?

javascript - 使用 jQuery 拦截表单提交

Javascript - 带有 PDF.js 的 pdf 总页数?

c++ - 类原型(prototype)

javascript - 将 __proto__ 分配给接口(interface)以将其转换为对象 - 聪明还是危险?

JavaScript 好的部分 : unshift function

javascript - 正则表达式提取字符串的前 10 个字符

javascript - 在循环中创建命名的 javascript 对象