我最近开始学习JavaScript以创建HTML5游戏,而且我遇到了一个我很难理解的行为。
作为一个例子,我有一个构造函数,用每次游戏更新时应该执行的一系列动作(例如动画,移动等)初始化新的精灵。 This JSFiddle演示了一个基本实现。
基本上,我很困惑为什么这不起作用......
Sprite = function () {
this.actions = [this.animate];
};
Sprite.prototype = {
animate: function () { /* animate the sprite */ },
update: function () {
this.actions[0](); // doesn't do anything (?)
}
};
...但这确实
Sprite = function () {
this.actions = [this.animate];
this.holder = 'whatever';
};
Sprite.prototype = {
animate: function () { /* animate the sprite */ },
update: function () {
this.holder = this.actions[0];
this.holder(); // executes animate function as desired
}
};
对于我没有经验的人来说,两个例子似乎都应该做同样的事情。那么,如果我直接致电this.actions[0]()
,为什么不会发生任何事情,但如果我将this.actions[0]
分配给this.holder
,然后致电this.holder()
,那么它的工作正常吗?
答案 0 :(得分:4)
调用函数时,会在函数内为名为this
的局部变量赋值。
除非你做了一些改变(例如new
,bind()
,call()
,apply()
),否则该值将成为调用它的对象。在foo.bar()
函数中使用this === foo
bar
。
this.actions[0]()
使this
等于actions
属性的值
this.holder()
使this
等于调用函数中this
的值。
你的功能必须取决于this
的值来做它做的任何事情。
答案 1 :(得分:3)
解决此问题的两种方法:
Sprite = function () {
this.actions = [this.animate.bind(this)];
};
或者:
update: function () {
this.actions[0].call(this);
}