Rya*_*yan 44 javascript animation object this
我正在使用,webkitRequestAnimationFrame
但我在一个对象内部使用它时遇到了麻烦.如果我传递this
它将使用的关键字window
,我找不到使用指定对象的方法.
例:
Display.prototype.draw = function(){
this.cxt.clearRect(0, 0, this.canvas.width, this.canvas.height);
//Animation stuff here.
window.webkitRequestAnimationFrame(this.draw);
};
Run Code Online (Sandbox Code Playgroud)
我也试过这个,但无济于事:
Display.prototype.draw = function(){
this.cxt.clearRect(0, 0, this.canvas.width, this.canvas.height);
//Animation stuff here.
var draw = this.draw;
window.webkitRequestAnimationFrame(draw);
};
Run Code Online (Sandbox Code Playgroud)
Mat*_*all 80
我正在尝试传递display.draw这是webkitRequestAnimationFram所在的函数.
webkitRequestAnimationFrame
可能会调用你传入的函数,如下所示:
function webkitRequestAnimationFrame(callback)
{
// stuff...
callback();
// other stuff...
}
Run Code Online (Sandbox Code Playgroud)
此时,您已将draw
函数与其调用上下文分离(分离).您需要将function(draw
)绑定到其上下文(实例Display
).
您可以使用Function.bind
,但这需要JavaScript 1.8支持(或者只使用推荐的补丁).
Display.prototype.draw = function()
{
// snip...
window.webkitRequestAnimationFrame(this.draw.bind(this));
};
Run Code Online (Sandbox Code Playgroud)
Jam*_*rld 21
现在ES6/2015就在这里,如果你正在使用一个转换器,那么一个箭头函数有词汇this
绑定,所以而不是:
window.webkitRequestAnimationFrame(this.draw.bind(this));
Run Code Online (Sandbox Code Playgroud)
你可以做:
window.webkitRequestAnimationFrame(() => this.draw());
Run Code Online (Sandbox Code Playgroud)
这有点清洁.
我已经有效地使用了这种方法,可以将Typescript转换为ES5.
我不能保证这是一个好主意,我是对的,但在每个requestAnimationFrame上运行.bind意味着在每次迭代时创建一个新函数.这对我来说听起来不对.
这就是为什么在我的项目中我缓存绑定函数以避免反模式.
简单的例子:
var Game = function () {
this.counter = 0;
this.loop = function () {
console.log(this.counter++);
requestAnimationFrame(this.loop);
}.bind(this);
this.loop();
}
var gameOne = new Game();
Run Code Online (Sandbox Code Playgroud)
如果你有一个带有原型继承的更复杂的项目,你仍然可以在object的构造函数中创建一个带有"this"的缓存函数
var Game = function () {
this.counter = 0;
this.loopBound = this.loop.bind(this);
this.loopBound();
}
Game.prototype.loop = function () {
console.log(this.counter++);
requestAnimationFrame(this.loopBound);
}
var gameOne = new Game();
Run Code Online (Sandbox Code Playgroud)
思考? http://jsfiddle.net/3t9pboe8/(在控制台中查看)