关于javascript:这会在全球启用“use strict”吗?

Would this enable “use strict” globally?

类似但不相同的是,如何在全球范围内启用ecmascript"use strict"?

我已经购买了JavaScript模式,它建议启用严格的使用。将它添加到二十多个javascript文件中可能有点麻烦,因此全局启用它将是一件好事。我最初想在main.js的顶部添加如下内容:

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

然而,我当时认为它可能只对那个文件启用它。然后我想到了这个:

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

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


DR:

不,一个script元素中的"use strict"不会将"use strict"强加给其他script元素中的代码。它只适用于它所属的源文本。

(另一方面,在问题的末尾重新加上script标记:如果script元素有src元素,则它被视为"文档"并被忽略的任何内联文本。)

更新:

现在规范中更清楚了(也许在ES5中很清楚,但对我来说不清楚),是的,单独的script元素对于"use strict"来说是单独的。原始答案中下面的引用已经稍微更改为说"源文本"而不是"代码单元",脚本和模块部分将更加详细。

原始答案:

说明书上说:

Because strict mode is selected at the level of a syntactic code unit, strict mode only imposes restrictions that have local effect within such a code unit. Strict mode does not restrict or modify any aspect of the ECMAScript semantics that must operate consistently across multiple code units.

(4.2.2节)

所以问题是:不同的script标记是否有不同的语法代码单元?

V8(Chrome中的javascript引擎)似乎认为它们是独立的,因此将单个"use strict";放在页面顶部的全局范围内是行不通的。也许这是我还没有找到的地方,但无论如何,这是一个合理的解释。

假设没有显示对foo的声明,则该代码将成为正常模式下隐式全局变量恐怖的牺牲品:

1
2
3
4
5
6
7
8
9
function test() {
    try {
      foo ="bar";
      display("foo =" + foo);
    }
    catch (e) {
      display("Exception:" + e);
    }
}

在正常模式下,创建一个新的全局变量foo,值为"bar",并显示"foo = bar"消息。在严格模式下,由于foo未定义,会引发异常。

如果我将这个脚本标记放在一个页面中:

1
2
3
4
5
6
7
8
9
10
"use strict";
function test() {
    try {
      foo ="bar";
      display("foo =" + foo);
    }
    catch (e) {
      display("Exception:" + e);
    }
}

…我得到了预期的异常(实况示例)。不过,如果我把它们放在单独的script标签上:

1
2
3
4
5
6
7
8
9
10
11
12
"use strict";


function test() {
    try {
      foo ="bar";
      display("foo =" + foo);
    }
    catch (e) {
      display("Exception:" + e);
    }
}

我没有得到例外(在V8上)(示例)。如果你考虑浏览器和JavaScript引擎是如何交互的,这是合理的。

同样地,如果函数在另一个文件中关闭,我会这样做:

1
2
3
"use strict";

<script src="/inatoq">

我没有得到例外(例如),大概是出于同样的原因。

注意这里的示例标记:

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

无效。script标记可以具有src属性或内容,但不能同时具有两者。(基本上,这里的细节是[HTML5]和[HTML4.01]。)如果它有一个src元素,那么浏览器应该忽略内容,大多数情况下是这样。大多数。-)


jslint突然报告:使用"use strict"的函数形式

1
2
3
4
5
6
(function () {
   "use strict";
    // put all of your strict code here


}());


不,脚本标记被认为是programs,因此是code units"use strict"不应该从一个脚本标记转移到另一个脚本标记。

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