【发布时间】:2012-07-05 22:03:00
【问题描述】:
更新:
也许函数调用的方式是罪魁祸首,所以这里是它:
2 JS 文件
Main.js:自调用(非严格)函数,为“(on)load”事件添加事件侦听器。
回调调用加载器函数,该函数解析 location.pathname,调用 init 函数,分离/删除“(on)load”侦听器并返回 null(显式)。
PageSpecific.js:包含 _init 函数,在正文中添加了几个事件侦听器。
这些侦听器之一的回调(也从闭包返回)调用使用 argument.callee 作为递归引用的严格函数。
返回事件处理程序的闭包可能 - 取决于浏览器 - 或者可能不绑定和取消绑定其他事件,但我认为这无关紧要,因为这是模仿 IE 中的 onchange 事件
我希望这是相当清楚的,所以它:
anon。 F => eventlistener
=> 处理程序(已命名但在匿名 F 中声明)=> pageloader =>
init => eventListener
闭包返回的绑定函数
=> 调用严格函数
顺便说一句:Here's a trimmed down version of the _init function 被称为,我实际上正在使用。更具体地说:将事件侦听器和 - 处理程序绑定在一起的闭包。这是我的另一个冗长的问题,似乎没有人知道答案... hint ;-)
我正在调试一些相当大(且复杂)的 JavaScript。在这样做时,我注意到我有一个函数,使用严格模式可以正常工作,但如果我没记错的话,应该抛出错误。由于脚本相当庞大和复杂(事件委托、堆叠闭包等),这里有一个简单的例子:
function withCalleeRecursion(foo)
{
'use strict';//strict throws typeError on arguments.callee
foo = foo.replace(/(a|b)+/gi, function (p1,p2)
{
if (p1.match(/(a|b){2,}/i))
{
return p1.replace(/(a|b)/gi,arguments.callee);//no errors
}
return (p2.match(/a/i) ? 'X':'Y');
});
return foo;
}
(function()
{//not strict
alert(withCalleeRecursion('Abba makes me barf'));
})();
在我的实际脚本中,这非常好。但是,当我将其粘贴到 Firebug 和 chrome 控制台中时,会引发错误。我试过这段代码here,所以IE也应该抛出错误,但是当我在IE的调试器中运行代码时,它工作得很好。据我所知,更改文档类型(尝试过 html5 和 html4)没有区别。
我认为(大多数)浏览器对 'use strict'; 指令的要求并不像它的名字所暗示的那样严格吗?当解析脚本时检测到可能的错误时,浏览器似乎选择忽略它。这是真的吗?
同时,出于谨慎起见,我对功能做了些微改动。由于我在这里看到很多人想知道如何在严格模式下获得 callee 引用,因此我也将其粘贴在这里:
function withCalleeRecursion(foo)
{
'use strict';
foo = foo.replace(/(a|b)+/gi, function abR(p1,p2)
{
if (p1.match(/(a|b){2,}/i))
{
return p1.replace(/(a|b)/gi,abR);
}
return (p2.match(/a/i) ? 'X':'Y');
});
return foo;
}
为回调命名,仅此而已。
【问题讨论】:
-
来自MSDN - “Internet Explorer 10 之前的 Internet Explorer 版本不支持严格模式。”您认为
arguments.callee应该在严格模式下抛出错误是正确的。 -
严格模式实现背后的想法是,
"use strict";在不支持的浏览器中的声明将完全无害。 -
很公平,我也这么认为......不过,该脚本也适用于 FF 和 chrome。两个最新版本 - 他们确实支持
strict mode -
@EliasVanOotegem - 当我运行 your code in JSFiddle 时,Chrome 会抛出预期的 TypeError。
-
我也设置了一个小提琴,我也得到了错误。我在那里尝试了所有的文档类型,每次我得到错误。也许它与调用堆栈有关?我将更新问题以给出函数调用方式的示意图
标签: javascript recursion strict