Javascript 带有此关键字的 requestAnimationFrame
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6065169/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
requestAnimationFrame with this keyword
提问by Ryan
I'm using webkitRequestAnimationFrame
but I'm having trouble using it inside of an object. If I pass the this
keyword it will use window
and I can't find a way for it to use the specified object instead.
我正在使用,webkitRequestAnimationFrame
但在对象内部使用它时遇到问题。如果我传递了this
它将使用的关键字,但window
我找不到一种方法来代替它使用指定的对象。
Example:
例子:
Display.prototype.draw = function(){
this.cxt.clearRect(0, 0, this.canvas.width, this.canvas.height);
//Animation stuff here.
window.webkitRequestAnimationFrame(this.draw);
};
I have also tried this but to no avail:
我也试过这个,但无济于事:
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);
};
回答by Matt Ball
I'm trying to pass display.draw which is the function in which webkitRequestAnimationFram resides.
我试图传递 display.draw 这是 webkitRequestAnimationFram 所在的函数。
webkitRequestAnimationFrame
will presumably call the function you pass in, something like this:
webkitRequestAnimationFrame
大概会调用您传入的函数,如下所示:
function webkitRequestAnimationFrame(callback)
{
// stuff...
callback();
// other stuff...
}
At this point, you have dissociated (detached) the draw
function from its invocation context. You need to bind the function (draw
) to its context (the instance of Display
).
此时,您已将draw
函数与其调用上下文分离(分离)。您需要将函数 ( draw
)绑定到其上下文( 的实例Display
)。
You can use Function.bind
, but this requires JavaScript 1.8 support(or just use the recommended patch).
您可以使用Function.bind
,但这需要 JavaScript 1.8 支持(或仅使用推荐的补丁)。
Display.prototype.draw = function()
{
// snip...
window.webkitRequestAnimationFrame(this.draw.bind(this));
};
回答by James World
Now that ES6/2015 is here, if you are using a transpiler then an arrow function has lexical this
binding so instead of:
现在 ES6/2015 来了,如果您使用的是转译器,那么箭头函数具有词法this
绑定,而不是:
window.webkitRequestAnimationFrame(this.draw.bind(this));
you can do:
你可以做:
window.webkitRequestAnimationFrame(() => this.draw());
which is a bit cleaner.
这更干净一些。
I've used this effectively with Typescript transpiling to ES5.
我已经在 Typescript 转换为 ES5 时有效地使用了它。
回答by Pawel
I can't guarantee that this is a good idea and that I'm right, but running .bind on every requestAnimationFrame means creating a new function on every iteration. It just doesn't sound right to me.
我不能保证这是个好主意而且我是对的,但是在每个 requestAnimationFrame 上运行 .bind 意味着在每次迭代时创建一个新函数。这对我来说听起来不对。
That's why in my project I cached the bound function to avoid the anti-pattern.
这就是为什么在我的项目中我缓存了绑定函数以避免反模式。
Simple example:
简单的例子:
var Game = function () {
this.counter = 0;
this.loop = function () {
console.log(this.counter++);
requestAnimationFrame(this.loop);
}.bind(this);
this.loop();
}
var gameOne = new Game();
If you have a more complex project with prototype inheritance you can still create a cached function with "this" bound in object's constructor
如果你有一个更复杂的原型继承项目,你仍然可以创建一个缓存函数,在对象的构造函数中绑定“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();
Thoughts? http://jsfiddle.net/3t9pboe8/(look in the console)
想法? http://jsfiddle.net/3t9pboe8/(在控制台中查看)
回答by bogdan
how about this:
这个怎么样:
Display.prototype.draw = function(){
this.cxt.clearRect(0, 0, this.canvas.width, this.canvas.height);
//Animation stuff here.
window.webkitRequestAnimationFrame( $.proxy(function() {this.draw()}, this) );
};
...assuming you use jquery
...假设您使用 jquery
回答by Tomá?
you have not to use "this". Keep it simple.
你不必使用“这个”。把事情简单化。
var game = {
canvas:null,
context:null,
init:function(){
// init canvas, context, etc
},
update:function(){
//do something
game.render();
requestAnimationFrame(game.update, game.canvas);
},
};
回答by MortezaE
Beside bind
method, and arrow function solution (offered by Jamaes World's answer), Another (rather old) work around could be:
除了bind
方法和箭头函数解决方案(由 Jamaes World 的答案提供),另一个(相当旧的)解决方法可能是:
var self = this
window.webkitRequestAnimationFrame(
function() {
self.draw()
}
);
回答by Oleg Isonen
And also you might want to use requestAnimationFrame shim to make it work on all browsers https://github.com/kof/animation-frame
而且你可能想使用 requestAnimationFrame shim 让它在所有浏览器上工作https://github.com/kof/animation-frame