JavaScript的严格模式是如何实现的
How is JavaScript's strict mode implemented
>更新:
也许调用函数的方式是罪魁祸首,所以这里是:
2 个 JS 文件
主.js:自调用(非严格)函数,为"(on)load"事件添加事件侦听器。
回调调用加载器函数,该函数解析 location.pathname,并调用 init 函数,并分离/删除"(on)load"侦听器并返回 null(显式)。
PageSpecific.js:包含_init函数,向正文添加几个事件侦听器。
其中一个侦听器的回调(也从闭包返回)调用使用 argument.callee 作为递归引用的严格函数。
返回事件处理程序的闭包可能 - 取决于浏览器 - 或者可能不会绑定和解绑其他事件,但我认为这在这里无关紧要,因为这是模仿 IE 中的 onchange 事件<9
我希望这是相当清楚的,所以它:
匿名。 F => 事件侦听器 =>处理程序(命名但在 anon F 中声明)=> 页面加载器 =>
初始化 => 事件监听器
闭包
返回的绑定函数 => 调用严格函数
顺便说一下:这是我实际使用的调用的_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;
}
命名回调,仅此而已。
这可能是因为浏览器控制台使用 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
})();
也许这篇文章可以帮助你了解更多。无论如何,解决方案就是您提到的解决方案,错误是因为访问 arguments.caller 和 arguments.callee 在严格模式下抛出异常。因此,需要命名要引用的任何匿名函数。
- 如何使用动画实现纸张推车
- 客户端服务器REST API captcha实现
- 如何实现此布局
- Meteor忘记了密码的实现
- 使用Native Sockets在Android中实现WebSockets
- 在样板文件中实现Ajax
- instanceof是如何在JavaScript中实现的
- 如何正确实现Jquery多选小部件
- 实现一个建立在google.com之上的自定义搜索引擎
- 多个组件是如何实现的
- window.location使用jquery mobile实现chrome跳转
- 如何在OpenERP中实现网络摄像头
- Node.js使用Series函数(模式?)实现流控制时出现意外结果
- javascript加密实现,包括可信否认
- 实现比较方法的最佳实践是什么;s的比较类型是在运行时选择的
- 如何让程序员在javascript中实现正确的回调
- 如何使用自定义辅助对象(handler)实现嵌套的每个循环
- AngularJS智能表全局配置实现
- Expressjs/AngularJS:实现req-flash后出错
- Java' Rhino实现实现了哪个JavaScript (ECMAScript)版本(更新策略是什么?)