28

与如何在全局范围内启用 ECMAScript “使用严格”类似,但又不一样

我已经购买了JavaScript Patterns,它建议启用 use strict。将它添加到两打 javascript 文件中会有点麻烦,因此在全球范围内启用它会很好。我最初想像这样添加到我的 main.js 的顶部:

"use strict" 
require({
    priority: ["jquery", "raphael", "myapp"] 
});

但是,我随后认为它可能只会为该文件启用它。然后我想到了这个:

<script data-main="lib/main" src="lib/require.js">"use strict"</script>

这些中的任何一个都会全局启用 ECMAScript 5 严格模式吗?

4

3 回答 3

44

TL;博士

不,一个元素"use strict"中的一个script元素不会强加于"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);
    }
}

在正常模式下,这会创建一个foo值为“bar”的新全局变量并显示"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>

我没有得到异常(example),大概是出于同样的原因。

请注意,您的示例标签在这里:

<script data-main="lib/main" src="lib/require.js">"use strict"</script>

是无效的。script标签可能具有属性或内容但不能同时具有两者。(嗯,基本上;细节在这里[HTML5] 和这里[HTML 4.01]。)如果它有一个元素,浏览器应该忽略内容,大多数人都会这样做。最多。:-)srcsrc

于 2011-06-26T12:21:31.793 回答
8

JSLint 突然报告:使用“use strict”的函数形式

(function () {
    "use strict";
    // put all of your strict code here


}());
于 2012-04-12T20:49:19.113 回答
6

不,脚本标签被考虑programs并因此code units"use strict"不应从一个脚本标签转移到另一个。

每个脚本标签都是单独解释的,实际上有自己的范围。这个范围并不明显,因为全局声明的所有内容都将在全局对象上结束,但它仍然存在。该字符串"use strict"将在 /script 标记的末尾被垃圾收集,program因为它没有指针/引用。

于 2011-06-26T12:50:25.710 回答