You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

封装requestAnimationFrame循环至类中丢失this引用的解决方法

解决requestAnimationFrame中类私有方法this丢失的问题

你遇到的错误核心原因是:当直接把私有方法#loop传给window.requestAnimationFrame时,函数的执行上下文发生了变化。第一次调用this.#loop()时,this指向Alerter实例,但requestAnimationFrame异步调用#loop时,this会默认指向全局对象(严格模式下为undefined),因此无法访问实例的私有属性#counter。

以下是三种可行的解决方案:

方案一:用箭头函数包裹调用

箭头函数不会绑定自身的this,它会继承当前上下文的this(即#loop执行时的Alerter实例),以此保留正确的指向:

class Alerter {
    
    #counter = 0;
    
    start() {
        this.#loop();
    }
    
    #loop() {
        const yes = confirm("Counter " + this.#counter + ". Continue?");
        
        if (!yes) {
            return;
        }
        
        this.#counter++;
        
        // 箭头函数保留this指向
        window.requestAnimationFrame(() => this.#loop());
    }
}

方案二:在构造函数中绑定this

通过bind方法将#loop的this永久绑定到Alerter实例,后续无论如何调用#loop,this都不会丢失:

class Alerter {
    
    #counter = 0;
    
    constructor() {
        // 绑定私有方法的this到当前实例
        this.#loop = this.#loop.bind(this);
    }
    
    start() {
        this.#loop();
    }
    
    #loop() {
        const yes = confirm("Counter " + this.#counter + ". Continue?");
        
        if (!yes) {
            return;
        }
        
        this.#counter++;
        
        window.requestAnimationFrame(this.#loop);
    }
}

方案三:用类字段箭头函数定义私有方法

直接将#loop定义为类字段的箭头函数,它的this会始终指向Alerter实例,无需额外绑定操作:

class Alerter {
    
    #counter = 0;
    
    start() {
        this.#loop();
    }
    
    // 箭头函数形式的私有方法,this永久指向实例
    #loop = () => {
        const yes = confirm("Counter " + this.#counter + ". Continue?");
        
        if (!yes) {
            return;
        }
        
        this.#counter++;
        
        window.requestAnimationFrame(this.#loop);
    }
}

各方案对比

  • 方案一:写法简单直观,适合单次或少量异步调用场景,每次调用会创建新箭头函数,但性能开销可忽略。
  • 方案二:仅在实例初始化时绑定一次,不会重复创建函数,适合需要多次复用方法的场景。
  • 方案三:代码最简洁,但每个实例都会生成独立的#loop函数副本,内存开销略高于前两种,适合小型类或实例数量不多的场景。

内容的提问来源于stack exchange,提问作者coderodde

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 05:17:22