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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 20:05:23  来源:igfitidea点击:

requestAnimationFrame with this keyword

javascriptobjectanimationthis

提问by Ryan

I'm using webkitRequestAnimationFramebut I'm having trouble using it inside of an object. If I pass the thiskeyword it will use windowand 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 所在的函数。

webkitRequestAnimationFramewill 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 drawfunction 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 thisbinding 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 bindmethod, 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