这会在全球范围内实现"use strict"吗?



类似但不相同,如何全局启用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标记的末尾进行垃圾收集,因为它没有指针/引用。

最新更新