【问题标题】:"Uncaught Type" error with requestAnimationFramerequestAnimationFrame 出现“未捕获类型”错误
【发布时间】:2013-12-01 03:04:03
【问题描述】:

所以我用 requestAnimationFrame 编写了一个工作应用程序(实际上是一半)。在项目变得过于复杂之前,我急于以面向对象的风格重写它,以便我们可以更好地实现插件(并且还可以在不更改整个应用程序的情况下修复模块)。事实上,该应用程序的第一个版本确实是一团糟,由大量测试代码组成。

所以我有以下内容:

Aventura.prototype.update = function() {
  var av = this;
  requestAnimationFrame(av.update);

  /* ... frame code ... */
};

我在控制台日志中得到“Uncaught TypeError: Type error”,就在 requestAnimationFrame 行中。我知道我的浏览器有一个正确的 requestAnimationFrame 实现,因为我完美地使用了我的应用程序的混乱版本。

我得出的结论是它引发了异常,因为我正在调用一个方法,该方法是调用者自己的父对象的成员(我知道这是完全相同的方法,但问题显然不在于 self-打电话,因为那是英国皇家空军应该做的)。有什么问题的线索吗?

【问题讨论】:

    标签: javascript html requestanimationframe


    【解决方案1】:

    这与requestAnimationFrame 无关。这是一个与传递函数有关的基本JavaScript问题,以及this的含义。

    人们倾向于认为对象内部的函数值属性,例如下面的myFn

    var myObj = {
        myFn: function() {console.log(this);}
    };
    

    不知何故将myObj“烤入”为this。错误的。 this 仅在函数被调用时分配。如果我说myObj.myFn()this 变成myObj,但我可以很容易地说myObj.myFn.call(otherObj)this 变成别的东西。

    当将函数作为参数传递给setTimeout、promise 或requestAnimationFrame 时,这一点变得很重要。只是传递myObj.myFn 传递函数,但它没有关联的thisrequestAnimationFrame 不知道这个函数来自哪里以及用什么 this 来调用它,所以它用 thiswindownull 或 0 或 undefined 或谁来调用它知道什么。这会导致错误。

    解决问题的最简单方法就是简单地说

    requestAnimationFrame(function() {av.update(); });
    

    现在 update 使用正确的 this 调用。

    一种更复杂、等效的方法是

    requestAnimationFrame(av.update.bind(av));
    

    其他说明

    我认为您将函数本身传递给requestAnimationFrame 的方式不会很好。您实际上是在设置一个递归调用链,最终堆栈会溢出。您需要将要在requestAnimationFrame 回调上执行的逻辑与请求帧的逻辑分开。

    【讨论】:

    • 你的意思是requestAnimationFrame调用方法应该和update方法本身分开?
    • 是的,我就是这个意思。
    【解决方案2】:

    我最终在这里找到了另一个问题的答案。我不认为它被归类为重复,因为这两个问题都是以不同的方式提出的,有人可以找到一个但找不到另一个问题(我自己在整个网络上寻找了一个类似的问题,但从来没有遇到过这个问题可能重复)。

    How to call requestAnimFrame on an object method?

    【讨论】:

      猜你喜欢
      • 2022-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-29
      • 2014-12-07
      • 2015-09-15
      相关资源
      最近更新 更多