0

更新:

也许函数被调用的方式是罪魁祸首,所以这里是它:

2 个 JS 文件
  Main.js:自调用(非严格)函数,为“(on)load”事件添加事件侦听器。
回调调用加载器函数,该函数解析 location.pathname,并调用 init 函数,并分离/删除“(on)load”侦听器并返回 null(显式)。

  PageSpecific.js:包含 _init 函数,在正文中添加了几个事件侦听器。
这些侦听器之一的回调(也从闭包返回)调用使用 argument.callee 作为递归引用的严格函数。
返回事件处理程序的闭包可能 - 取决于浏览器 - 或者可能不绑定和取消绑定其他事件,但我认为这无关紧要,因为这是模仿 IE <9 中的 onchange 事件

我希望这是相当清楚的,所以它:
anon。F => eventlistener
             => 处理程序(命名但在匿名 F 中声明) => pageloader =>
                  init =>
                  闭包返回的 eventListener 绑定函数
                      =>调用严格函数

顺便说一句:这是我实际使用的被调用函数的精简版本。_init更具体地说:将事件侦听器和 - 处理程序绑定在一起的闭包。这是我的另一个冗长的问题,似乎没有人知道答案......提示;-)


我正在调试一些相当大(和复杂)的 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 控制台中时,会引发错误。我在这里试过这段代码,所以 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;
}

命名回调,仅此而已。

4

2 回答 2

2

这可能是因为浏览器控制台使用eval(),这会改变一些事情。尽管将"use strict";传递给的代码字符串放在开头eval()可以按预期工作,但控制台实现可能会将代码添加到您在控制台中键入的字符串的前面,这意味着它"use strict";不再是执行的第一条语句,因此会被忽略。

在以下文章中有对此的参考和建议的解决方法:

http://javascriptweblog.wordpress.com/2011/05/03/javascript-strict-mode/

建议的解决方法是将控制台中的代码包装在一个立即执行的函数中:

(function() {
    "use strict";
    nonExistentVariable = 1; // Error is now thrown
})();
于 2012-07-05T13:48:05.573 回答
0

也许这篇文章可以帮助您了解更多。无论如何,解决方案是您提到的那个,错误是因为访问 arguments.caller 和 arguments.callee 在严格模式下抛出异常。因此,您要引用的任何匿名函数都需要命名。

于 2012-07-05T13:36:11.663 回答