【问题标题】:Typescript "this" instance is undefined in class打字稿“this”实例在类中未定义
【发布时间】:2018-03-16 19:15:48
【问题描述】:

我在网上找到了这个,现在正在尝试将其放入 TS 中。

运行以下抛出Uncaught TypeError: Cannot set property 'toggle' of null

@Injectable()
export class HomeUtils {
    private canvas: HTMLCanvasElement;
    private context;
    private toggle = true;

    constructor() { }

    public startNoise(canvas: HTMLCanvasElement) {
        this.canvas = canvas;
        this.context = canvas.getContext('2d');
        this.resize();
        this.loop();
    }

    private resize() {
        this.canvas.width = window.innerWidth;
        this.canvas.height = window.innerHeight;
    }

    private loop() {
        this.toggle = false;
        if (this.toggle) {
            requestAnimationFrame(this.loop);
            return;
        }
        this.noise();
        requestAnimationFrame(this.loop);
    }

    private noise() {
        const w = this.context.canvas.width;
        const h = this.context.canvas.height;
        const idata = this.context.createImageData(w, h);
        const buffer32 = new Uint32Array(idata.data.buffer);
        const len = buffer32.length;
        let i = 0;

        for (; i < len;) {
            buffer32[i++] = ((255 * Math.random()) | 0) << 24;
        }

        this.context.putImageData(idata, 0, 0);
    }

}

我迷路了。

【问题讨论】:

标签: angular typescript


【解决方案1】:

方法不会捕获this,而是依赖于调用者使用正确的this 调用它们。比如:

this.loop() // ok
let fn = this.loop;
fn(); // Incorect this
fn.apply(undefined) // Undefined this

由于您将loop 传递给另一个函数requestAnimationFrame,您需要确保this 是从声明上下文中捕获的,而不是由requestAnimationFrame 决定的:

您可以将箭头函数传递给requestAnimationFrame

private loop() {
    this.toggle = false;
    if (this.toggle) {
        requestAnimationFrame(() => this.loop());
        return;
    }
    this.noise();
    requestAnimationFrame(() => this.loop());
} 

或者你可以让循环成为箭头函数而不是方法:

private loop = () => {
    this.toggle = false;
    if (this.toggle) {
        requestAnimationFrame(this.loop);
        return;
    }
    this.noise();
    requestAnimationFrame(this.loop);
}

第二种方法的优点是不会在每次调用 requestAnimationFrame 时创建一个新的函数实例,因为这会被大量调用,您可能希望使用第二种方法来最小化内存分配。

【讨论】:

  • 好的,我明白了,这会给我带来麻烦,谢谢正确的解释。
  • 如果我的loop() 函数有一个time 参数:loop(time: number) 怎么办?
  • “方法无法捕捉到这一点”——多么棒的语言
【解决方案2】:

这是对requestAnimationFrame 的呼叫。您正在传递一个未绑定到上下文的函数,因此,在对 loop 的调用中没有 this

将调用改为:

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

与普通函数相反,箭头函数绑定到this

【讨论】:

    猜你喜欢
    • 2012-11-15
    • 1970-01-01
    • 2021-08-30
    • 1970-01-01
    • 2013-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多