如何实现JavaScript的严格模式

时间:2012-07-05 13:30:00

标签: javascript recursion strict

更新

也许调用函数的方式是责备,所以这就是它:

  

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

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

我希望这是相当清楚的,所以它是:星期一。 F => eventlistener
=> handler(命名但在anon F中声明)=> pageloader =>
init => eventListener
由闭包返回的绑定函数
=> 调用严格功能

顺便说一句:Here's a trimmed down version of the _init function被称为,我实际上正在使用。更具体地说:将事件Listener和 - handler绑定在一起的闭包。这是我的另一个长度问题,似乎没有人知道答案...... 提示; - )


我正在调试一些相当大(和复杂)的JavaScripts。在这样做的时候,我注意到我有一个函数,使用严格的模式工作正常,但如果我没有弄错,应该抛出错误。由于脚本相当大且复杂(事件委托,堆叠闭包等),这里有一个简单的例子:

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的调试器中运行代码时,它运行得很好。据我所知,更改doctype(试过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;
}

为回调命名,就是全部。

2 个答案:

答案 0 :(得分:2)

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

以下文章中提到了这一点以及建议的解决方法:

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

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

"use strict";

答案 1 :(得分:0)

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

相关问题