在声明时立即调用 Javascript 匿名函数是行不通的,稍后调用它才可以
[已回答]
我正在测试 html5 游戏浏览器的 fps。
我有这段代码:
var requestAnimationFrame = ( function() {
return window.requestAnimationFrame || //Chromium
window.webkitRequestAnimationFrame || //Webkit
window.mozRequestAnimationFrame || //Mozilla Geko
window.oRequestAnimationFrame || //Opera Presto
window.msRequestAnimationFrame || //IE Trident?
function(callback) { //Fallback function
window.setTimeout(callback, 1000/60);
}
})();
var hits = 0;
var last = new Date().getTime();
var step = (function(){
now = new Date().getTime();
hits += 1;
if( now - last >= 1000 ){
last += 1000;
console.log( "fps: "+ hits );
hits = 0;
}
requestAnimationFrame( step );
})();
它在 Chrome 上出现以下错误:未捕获错误:TYPE_MISMATCH_ERR:DOM 异常 17
第 #27 行:requestAnimationFrame(step );
W3 表示此错误是:如果对象的类型与与该对象关联的参数的预期类型不兼容。
但我实际上根本没有与 DOM 交互,除了 window
但如果我删除分配给 step
的匿名函数的调用括号,而只是声明该函数在新行中我输入:step();
它有效。
这是为什么?
两者不应该工作相同吗?
[answered]
I'm testing my browser's fps for an html5 game.
I have this code:
var requestAnimationFrame = ( function() {
return window.requestAnimationFrame || //Chromium
window.webkitRequestAnimationFrame || //Webkit
window.mozRequestAnimationFrame || //Mozilla Geko
window.oRequestAnimationFrame || //Opera Presto
window.msRequestAnimationFrame || //IE Trident?
function(callback) { //Fallback function
window.setTimeout(callback, 1000/60);
}
})();
var hits = 0;
var last = new Date().getTime();
var step = (function(){
now = new Date().getTime();
hits += 1;
if( now - last >= 1000 ){
last += 1000;
console.log( "fps: "+ hits );
hits = 0;
}
requestAnimationFrame( step );
})();
It gives the following error on Chrome:Uncaught Error: TYPE_MISMATCH_ERR: DOM Exception 17
On line #27: requestAnimationFrame( step );
W3 says this error is: If the type of an object is incompatible with the expected type of the parameter associated to the object.
But I'm not actually interacting with the DOM at all, except for window
But if I remove the calling parentheses of the anonymous function assigned to step
and instead just declare that function and on a new line I put:step();
It works.
Why is this?
Shouldn't both work the same?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

发布评论
评论(5)
我发现对这里发生的事情存在一些根本性的误解。例如,在第一个声明中:
var requestAnimationFrame = ( function() {
return window.requestAnimationFrame || //Chromium
window.webkitRequestAnimationFrame || //Webkit
window.mozRequestAnimationFrame || //Mozilla Geko
window.oRequestAnimationFrame || //Opera Presto
window.msRequestAnimationFrame || //IE Trident?
function(callback) { //Fallback function
window.setTimeout(callback, 1000/60);
}
})();
您正在创建一个匿名函数,然后立即调用它并将结果分配给一个变量。我不明白这有什么意义。以下内容同样有效:
var requestAnimationFrame =
window.requestAnimationFrame || //Chromium
window.webkitRequestAnimationFrame || //Webkit
window.mozRequestAnimationFrame || //Mozilla Geko
window.oRequestAnimationFrame || //Opera Presto
window.msRequestAnimationFrame || //IE Trident?
function(callback) { //Fallback function
window.setTimeout(callback, 1000/60);
};
现在没有匿名函数(除了那个小后备函数),它只是运行的代码。您可以对 step()
函数应用类似的简化。
您当前的代码本质上是“运行这个匿名函数并将其返回值分配给step
”。这有两个基本问题:
- 该函数不返回值,因此即使在运行之后
step
也将是未定义的。 - 即使函数确实返回了一个值,您也会在第一次运行时尝试在函数内部使用
step
,此时会分配给step 尚未发生。
解决此问题的最简单方法就是您已经执行的操作,即,将 step
声明为函数,然后在下一行运行它:
var step = function() { ... };
step();
或者您可以使用命名函数表达式:
(function step() {
...
requestAnimationFrame( step );
})();
这相当于:
(function () {
...
requestAnimationFrame( arguments.callee );
})();
不幸的是 IE 不太擅长命名函数表达式。
而且不幸的是(无论如何,从我的角度来看,不幸的是) arguments .callee
现已弃用,并且无法在严格模式下工作。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
requestAnimationFrame
需要一个函数,但在您的代码中,step
不是一个函数,它是undefined
因为您没有从您的代码返回任何值自调用函数。如果删除调用括号,那么
step
确实是一个函数。请参阅@Martin对此答案的评论。我指的是函数执行后
step
是未定义
的事实,但当然它也是未定义
当您第一次调用该函数时。requestAnimationFrame
expects a function, but in your code,step
is not a function, it isundefined
because you don't return any value from your self-invoking function.If you remove the calling parenthesis, then
step
is indeed a function.Please see @Martin's comment to this answer. I was referring to the fact that
step
isundefined
after the function is executed, but of course it is alsoundefined
when you invoke the function the first time.