我正在尝试开发一个小游戏,我有以下问题:我有一个伪类“Cannon”,每个Cannon都有一个数组,用于存储它应该守卫的区域和一个存储“入侵者”的数组进入其中一个守卫区域。我创建了下一个函数作为Cannon原型的一部分:
Cannon.prototype.checkIntruderLeftGuardedAreas = function(){
debugger;
this.intruders = this.intruders.filter(function(intruder){
for(var i = 0, l = this.guardedAreas.length; i < l; i ++)
{
if(intruder.inInsideGuardedArea(this.guardedAreas[i]))
{
return true;
}
}
return false;
});
}
在第三行,我试图过滤那些已经离开守卫区域的入侵者,但是“这个”引用了“窗口”而不是调用该函数的Cannon对象。
我也试过这段代码:
var intrudersArray = [];
for(var i = 0, l = this.guardedAreas.length; i < l; i ++)
{
for(var j = 0, k = this.intruders.length; j < k; j++)
{
if(this.intruders[j].inInsideGuardedArea(this.guardedAreas[i]))
{
intrudersArray.push(this.intruders[j]);
}
}
}
this.intruders = intrudersArray;
根据我的逻辑,这与前一段代码做了同样的事情:过滤入侵者数组。问题是在“if”开始的第6行,突然“this”引用“window”!在达到if条件之前,“this”引用调用该函数的Cannon对象。
答案 0 :(得分:2)
是的,范围可能会变得棘手,您可以尝试以下方法:
Cannon.prototype.checkIntruderLeftGuardedAreas = function(){
var self = this;
self.intruders = self.intruders.filter(function(intruder){
for(var i = 0, l = self.guardedAreas.length; i < l; i ++)
{
if(intruder.inInsideGuardedArea(self.guardedAreas[i]))
{
return true;
}
}
return false;
});
}
注意第var self = this;
行。它的目的是保存对你的cannon实例的引用,以便在嵌套回调中使用(注意this
self
filter
this
内部的self
},以避免范围问题,这种情况很常见在jQuery代码中。
这种做法确保你引用你的大炮而不需要跟踪{{1}},{{1}}正在发生的事情,乍看之下这是显而易见的。
答案 1 :(得分:0)
当您调用checkIntruderLeftGuardedAreas时,请绑定&#34;此&#34;来自被叫者的对象。
obj.checkIntruderLeftGuardedAreas.bind(this)(arg1, arg2, ..., argn);
在JavaScript中,这是一个上下文,而不是当前的类。
示例:定义一个输出&#34;此&#34;
的函数function lol(){console.log(this);}
现在调用该函数
洛尔();
你得到了窗口。
此外,定义一个函数,并在对象中调用它:
var obj = { abc: function(){lol(); }}
然后
obj.abc();
仍会让你开窗 你需要
var obj = { abc: function(){lol.bind(this)(); }}
当您调用函数
时,此上下文将更改为objobj.abc();
您可能必须这样做:
Cannon.prototype.checkIntruderLeftGuardedAreas = function(){
debugger;
this.intruders = this.intruders.filter(function(intruder){
for(var i = 0, l = this.guardedAreas.length; i < l; i ++)
{
if(intruder.inInsideGuardedArea(this.guardedAreas[i]))
{
return true;
}
}
return false;
}).bind(this);
}
注意&#34; bind&#34;在倒数第二行。