如何将RequestAnimationFrame与TypeScript对象一起使用?

时间:2014-02-21 03:28:01

标签: javascript this typescript requestanimationframe

我有一个想要在画布上绘图的对象。它将使用requestAnimationFrame开始游戏循环:

Contoso.ts

class Contoso
{
   //private ctx: CanvasRenderingContext2D;

   Initialize(ctx: CanvasRenderingContext2D) {
      //this.ctx = ctx;
      Render();
   }

   Render() {
      //...snip doing any actual drawing for the purpose of this question
      requestAnimationFrame(this.Render);
   }
}

app.ts

var contoso: Contoso;

contoso = new Contoso();
contoso.Initialize(canvas);

第一次有人拨打Initialize时,requestAnimationFrame设法正确拨打Render

第二次requestAnimationFrame来电Renderthis.Renderundefined并且崩溃了。

在初次调用Initialize之后,对象几乎被破坏了。

发生了什么事?

4 个答案:

答案 0 :(得分:32)

您丢失了this个背景信息。两个可能的修复:

class Contoso
{
   /* ... */

   // Use () => syntax so Render always gets 'this' context
   // from the class instance
   Render = () => {
      //...snip doing any actual drawing for the purpose of this question
      requestAnimationFrame(this.Render);
   }
}

替代修复可能稍微清楚一点,但是有更多分配的缺点(你可能不希望每帧分配1个闭包!)

   Render() {
      //...snip doing any actual drawing for the purpose of this question
      requestAnimationFrame(() => this.Render);
   }

答案 1 :(得分:6)

使用箭头语法(lambda):

requestAnimationFrame(() => this.Render());

这是一篇博客文章,详细解释了这个技巧的特殊性:

http://www.anotherchris.net/typescript/using-the-this-keyword-with-typescript-and-a-jquery-function/

答案 2 :(得分:2)

我找到的最佳方法。

requestAnimationFrame(this.Render.bind(this));

.bind(this)创建一个新的函数,其this关键字设置为提供的值。

奖金阅读

答案 3 :(得分:1)

在Firefox 49.0.1上,我收到了使用Ryan Cavanaugh解决方案的错误消息。

  

SyntaxError:错误的方法定义

为该行:

  

Render =()=> {

我发现的工作看起来像这样:

class Test{

    constructor(){

        this.Render = ()=> {
            requestAnimationFrame( this.Render );
        };

    }
}