类似但不相同,如何全局启用ECMAScript"use strict"?
我已经购买了JavaScriptPatterns,它建议启用严格使用。将它添加到二十多个javascript文件中会有点麻烦,因此在全局范围内启用它会很好。我最初想在main.js的顶部添加这样的内容:
"use strict"
require({
priority: ["jquery", "raphael", "myapp"]
});
然而,我当时认为它可能只会为该文件启用它。然后我想了想:
<script data-main="lib/main" src="lib/require.js">"use strict"</script>
这两者中的任何一个会在全局范围内启用ECMAScript 5严格模式吗?
TL;DR:
否,一个script
元素中的"use strict"
不会将"use strict"
强加给其他script
元素中的代码。它只适用于它所属的源文本。
(另外,请在问题末尾重新标记script
:如果script
元素具有src
,则它所具有的任何内联文本都被视为"文档",并被忽略。)
更新:
现在在规范中更清楚了(也许在ES5中很清楚,但对我来说不是),是的,单独的script
元素对于"use strict"
来说是分开的。原始答案中的以下引文略有更改,改为"源文本"而非"代码单元",脚本和模块部分将进行更详细的介绍。
原始答案:
说明书上写着:
因为严格模式是在句法代码单元的级别上选择的,所以严格模式只会在这样的代码单元内施加局部影响的限制。严格模式不限制或修改ECMAScript语义的任何方面,这些方面必须在多个代码单元之间一致操作。
(第4.2.2节)
所以问题是:不同的script
标签是否有不同的句法编码单位?
V8(Chrome中的JavaScript引擎)似乎认为它们是独立的,因此在页面顶部的全局范围中放置单个"use strict";
是不可行的。也许它是在我还没有找到的地方指定的,但无论如何,这是一个合理的解释。
假设foo
没有未显示的声明,则此代码将成为正常模式下隐式全局变量的恐怖:
function test() {
try {
foo = "bar";
display("foo = " + foo);
}
catch (e) {
display("Exception: " + e);
}
}
在正常模式下,这将创建一个值为"bar"的新全局变量foo
,并显示"foo = bar"
消息。在严格模式下,由于未定义foo
,因此会引发异常。
如果我把这个脚本标签放在一个页面上:
<script>
"use strict";
function test() {
try {
foo = "bar";
display("foo = " + foo);
}
catch (e) {
display("Exception: " + e);
}
}
</script>
我得到了预期的异常(实例)。如果我把它们放在单独的script
标签中,那么:
<script>
"use strict";
</script>
<script>
function test() {
try {
foo = "bar";
display("foo = " + foo);
}
catch (e) {
display("Exception: " + e);
}
}
</script>
我没有得到异常(在V8上)(示例)。如果你想想浏览器和JavaScript引擎是如何交互的,这是合理的。
同样,如果另一个文件中的功能关闭,我会这样做:
<script>
"use strict";
</script>
<script src="/inatoq"></script>
我没有得到例外(例子),大概也是出于同样的原因。
请注意,此处的示例标签:
<script data-main="lib/main" src="lib/require.js">"use strict"</script>
无效。script
标记可以具有src
属性或内容,但不能同时具有这两个属性。(好吧,基本上;详细信息在这里[HTML5]和这里[HTML4.01]。)如果它有src
元素,浏览器应该忽略内容,大多数浏览器都会忽略。大多数。:-)
JSLint突然报告:使用函数形式"使用严格的";
(function () {
"use strict";
// put all of your strict code here
}());
否,脚本标记被认为是programs
,因此是code units
。"use strict"
不应该从一个脚本标记转移到另一个。
每个脚本标记都是单独解释的,实际上都有自己的作用域。这个作用域是不可通知的,因为全局声明的所有内容都将最终出现在全局对象上,但它在那里是无保留的。字符串"use strict"
将在program
/script标记的末尾进行垃圾收集,因为它没有指针/引用。