" Uncaught Type" requestAnimationFrame出错

时间:2013-12-01 03:04:03

标签: javascript html5 requestanimationframe

所以我用requestAnimationFrame编写了一个有效的应用程序(实际上是其中的一半)。在项目过于复杂之前,我急于以面向对象的方式重写它,这样我们就可以更好地实现插件(并且还可以在不更改整个应用程序的情况下修复模块)。事实上,该应用程序的第一个版本实际上已经搞砸了很多测试代码。

所以我有以下内容:

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

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

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

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

2 个答案:

答案 0 :(得分:5)

这与requestAnimationFrame无关。这是与一般传递函数相关的基本JavaScript问题,以及this

的含义

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

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

某种方式myObj“在”this中“。错误。仅在函数调用时分配this。如果我说myObj.myFn()this变为myObj,但我可以轻而易举地说myObj.myFn.call(otherObj)this成为其他内容。

将函数作为参数传递给setTimeout,promises或requestAnimationFrame时,这一点很重要。只是通过myObj.myFn传递函数,但它没有关联的thisrequestAnimationFrame不知道此功能的来源以及this要调用它的内容,因此它使用this windownull来调用它,或0,或undefined,或谁知道什么。这会导致错误。

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

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

现在使用正确的update调用this

更复杂,更等效的方式是

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

其他说明

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

答案 1 :(得分:0)

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

How to call requestAnimFrame on an object method?