如果在构造函数中使用for循环,则私有变量不是特定于对象的:JavaScript
我面临一个奇怪的问题,请看下面的代码如果在构造函数中使用for循环,则私有变量不是特定于对象的:JavaScript,javascript,prototype,Javascript,Prototype,我面临一个奇怪的问题,请看下面的代码 var ApplicationParser = (function(){ ApplicationParser.prototype.messageFramer; ApplicationParser.prototype.isPreviousFetchingDirection; ApplicationParser.prototype.latestDataArrays = []; ApplicationParser.prototype.dataPointsArra
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];
var ApplicationParser=(函数(){
ApplicationParser.prototype.messageFramer;
ApplicationParser.prototype.isPreviousFetchingDirection;
ApplicationParser.prototype.LatestDataArray=[];
ApplicationParser.prototype.dataPointsArray=[];
ApplicationParser.prototype.chartObject;
ApplicationParser.prototype.titleLabel;
ApplicationParser.prototype.chartConfiguration;
ApplicationParser.prototype.htmlId;
函数ApplicationParser(url、dataPointArray、标题、htmlId、fetchSize){
this.messageFramer=newmessageframer(url,fetchSize);
this.isPreviousFetchingDirection=true;
this.messageFramer.FetchNextData(this,this.isPreviousFetchingDirection);
this.dataPointsArray=dataPointArray;
this.titleLabel=标题;
this.htmlId=htmlId;
for(var int=0;int
现在,如果您尝试访问这两个对象的“LatestDataArray”,那么它将显示[4,5,6];虽然“dataPointsArray”仍然不同。为什么“LatestDataArray”也不能显示不同的值
如果我用下面的代码替换上面的代码,那么问题就解决了
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;}());
var ApplicationParser=(函数(){
ApplicationParser.prototype.messageFramer;
ApplicationParser.prototype.isPreviousFetchingDirection;
ApplicationParser.prototype.LatestDataArray=[];
ApplicationParser.prototype.dataPointsArray=[];
ApplicationParser.prototype.chartObject;
ApplicationParser.prototype.titleLabel;
ApplicationParser.prototype.chartConfiguration;
ApplicationParser.prototype.htmlId;
函数ApplicationParser(url、dataPointArray、标题、htmlId、fetchSize){
this.messageFramer=newmessageframer(url,fetchSize);
this.isPreviousFetchingDirection=true;
this.messageFramer.FetchNextData(this,this.isPreviousFetchingDirection);
this.dataPointsArray=dataPointArray;
this.titleLabel=标题;
this.htmlId=htmlId;
var latArrayTemp=新对象();
for(var int=0;int
请说明其背后的原因,是否是for循环内部构造函数产生问题,如果是,则说明原因…?请说明其背后的原因,是否是for循环内部构造函数产生问题? 不,它与for循环无关。问题的根本原因是:
dataPointsArray
是app1
和app2
的实例变量——每个ApplicationParser
对象都有自己唯一的dataPointsArray
实例
但是,latestDataArrays
是ApplicationParser.prototype
中的一个字段,这意味着所有ApplicationParser
对象(app1
和app2
)将共享latestDataArrays
实例(除非他们声明它是latestDataArrays
指向其他东西。这正是第二个代码段的行为)
如何解决问题?
由于dataPointsArray
和latestDataArrays
是实例变量,请从ApplicationParser.prototype
中删除它们。也就是说,删除以下两行:
ApplicationParser.prototype.latestDataArrays = [];
ApplicationParser.prototype.dataPointsArray = [];
一些详细说明: 代码中发生了什么:
var-app=newapplicationparser(…)
?
调用newapplicationparser(…)
时,将执行以下步骤:
ApplicationParser.prototype
扩展它。我们称它为XApplicationParser
(构造函数),在函数内部使用X作为this
return
语句,则返回X应用程序
app1
和app2
会发生什么情况?
对于var app1=newapplicationparser(…)
语句,我们将其“X”称为Xapp1
对于var app2=newapplicationparser(…)
语句,我们将其“X”称为Xapp2
创建Xapp1后,在构造函数运行之前,Xapp1.dataPointsArray
指向ApplicationParser.prototype.dataPointsArray
和Xapp1.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]=…
仅更改此的对象的某些属性。最新的DataArray
指向
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共享latestDataArray
的对象,但它们的dataPointsArray
是唯一的
为什么第二个代码段有效?
由于以下语句,第二个代码段可以工作:
this.latestDataArrays = latArrayTemp;
此语句重新分配latestDataArray<
Xapp1.latestDataArrays === ApplicationParser.prototype.latestDataArrays // false, as Xapp1.latestDataArrays is L1 now.
Xapp2.latestDataArrays === ApplicationParser.prototype.latestDataArrays // false, as Xapp2.latestDataArrays is L2 now.