我正在用CraftyJS写一个小游戏。这是我想写的:
Crafty.scene('MainMap', function() {
this.player = Crafty.e('Player');
this.player.move(5, 5);
this.game_objects = [this.player];
isOccupied: function(x, y) {
for (var i = 0; i < this.game_objects.length; i++) {
// ...
}
}
if (!this.isOccupied(5, 5)) { ... }
// ...
}
不幸的是,这不能按预期工作;它不是一个匿名对象,但它是一个函数。我必须使用不同的语法,并传入我的对象,如下所示:
function isOccupied(x, y, game_objects) { ... }
// Same place as previous call to isOccupied
if (!isOccupied(x, y, this.gameObjects) { ... }
我很清楚为什么我必须将其声明为function isOccupied
而不是isOccupied: function
(因为它在函数内部,而不是对象)但是我不清楚{{1是的。它不会传递给函数。
是否有可能以某种方式将对象保留在某些非全局范围内,而不需要将它们传递到this
?
答案 0 :(得分:2)
您可以将父作用域分配给另一个变量,因此它将在您的闭包中可用。像这样......
Crafty.scene('MainMap', function() {
var self = this;
this.player = Crafty.e('Player');
this.player.move(5, 5);
this.game_objects = [this.player];
function isOccupied (x, y) {
for (var i = 0; i < self.game_objects.length; i++) {
// ...
}
}
}
答案 1 :(得分:2)
您的Crafty场景中存在语法错误。
这部分的冒号不应该在那里。在JavaScript中,冒号只用于对象。
// Wrong
isOccupied: function(x, y) {
for (var i = 0; i < this.game_objects.length; i++) {
// ...
}
}
// Right
function isOccupied(x, y) {
// ...
}
在您的函数中,this
引用全局对象(window
)。
编辑:
要解决此问题,请使用Function.prototype.bind
,如下所示:
function isOccupied(x, y) {
// ...
}.bind(this);
答案 2 :(得分:0)
进行更多研究后,似乎这是一个well-known issue,其中包含this
个关键字。它将在ECMAscript 5中修复。
总结一下:当您有多个嵌套级别时,this
关键字会混淆:
obj = {
speak: function() {
alert(this); // obj
inner = function() {
alert("inner: " + this); // window
};
}
};
解决方法是使用范围链,将变量分配给this
:
obj = {
speak: function() {
alert(this); // obj
var that = this;
inner = function() {
alert("inner: " + that); // obj instead of window
};
}
};
不幸的是,CraftJS让我在函数内部而不是对象。要声明子函数,我仍然必须将其指定为function isOccupied
:
Crafty.scene('MainMap', function() {
self = this; // new
this.player = Crafty.e('Player');
this.player.move(5, 5);
this.game_objects = [this.player];
function isOccupied(x, y) { // game_objects no longer passed in
for (var i = 0; i < self.game_objects.length; i++) { // uses self
// ...
}
}
if (!this.isOccupied(5, 5)) { ... }
// ...
}