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

将requestAnimationFrame作为对象属性调用时触发非法调用错误

解决Uncaught TypeError: Illegal invocation的问题

这个报错我之前踩过坑,核心原因就是方法的this指向不符合要求!咱们一步步捋清楚:

为什么会报错?

window.requestAnimationFrame是属于window对象的原生方法,它在执行时要求内部的this必须指向window。当你直接把它赋值给foo.requestAnimationFrame后,调用foo.requestAnimationFrame(foo.draw)时,这个方法内部的this就变成了foo对象,而不是原本的window——浏览器不允许这种"非法调用"原生API的操作,所以就抛出了Uncaught TypeError: Illegal invocation。

另外,你代码里还有个小错误:foo.requestAnimationFrame = window.requestAnimationFrame();这里多了括号!这会把调用requestAnimationFrame后的返回值(一个请求ID)赋值给属性,而不是方法本身,这肯定会出问题,得去掉括号。

几种可行的解决方案

方案1:用bind固定this指向

通过bind(window)生成一个新函数,让它内部的this永远指向window,同时如果你的draw方法需要用到foo的属性,也要给draw绑定this到foo:

var foo = {
  draw: function() {
    // 这里可以正常使用this访问foo的属性
    console.log("执行绘制逻辑", this);
    // 如果需要循环调用,记得再次绑定
    this.requestAnimationFrame(this.draw.bind(this));
  },
  init: function() {
    // 绑定requestAnimationFrame的this到window,不要加括号!
    this.requestAnimationFrame = window.requestAnimationFrame.bind(window);
    // 调用时绑定draw的this到foo
    this.requestAnimationFrame(this.draw.bind(this));
  }
};

foo.init();

方案2:调用时用call/apply指定this

如果不想修改requestAnimationFrame的绑定,也可以在调用时用call直接指定this为window:

var foo = {
  draw: function() {
    console.log("绘制中");
  },
  init: function() {
    // 直接赋值方法引用,不要加括号
    this.requestAnimationFrame = window.requestAnimationFrame;
    // 用call指定this为window,第二个参数是回调函数
    this.requestAnimationFrame.call(window, this.draw.bind(this));
  }
};

foo.init();

方案3:直接调用window.requestAnimationFrame(最简单)

如果没必要把requestAnimationFrame挂载到foo上,直接用原生的调用方式最省心,完全不会有this的问题:

var foo = {
  draw: function() {
    console.log("执行绘制");
    // 循环调用时直接用window的方法,同时绑定draw的this
    window.requestAnimationFrame(this.draw.bind(this));
  },
  init: function() {
    window.requestAnimationFrame(this.draw.bind(this));
  }
};

foo.init();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:30:54