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

Ian*_*oyd 9 javascript this requestanimationframe typescript

我有一个对象,我想在画布上绘图.它将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);
   }
}
Run Code Online (Sandbox Code Playgroud)

app.ts

var contoso: Contoso;

contoso = new Contoso();
contoso.Initialize(canvas);
Run Code Online (Sandbox Code Playgroud)

有人第一次打电话Initialize,requestAnimationFrame设法正确打电话Render.

第二次requestAnimationFrame打电话Render,this.Renderundefined和它崩溃.

这几乎就像是在初次调用之后对象被破坏了Initialize.

到底是怎么回事?

Rya*_*ugh 36

你失去了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);
   }
}
Run Code Online (Sandbox Code Playgroud)

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

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

  • @Ryan:第一个建议(即渲染 = () => { ... })效果很好。谢谢。 (2认同)

x0n*_*x0n 6

使用箭头语法(lambda):

requestAnimationFrame(() => this.Render());
Run Code Online (Sandbox Code Playgroud)

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

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