这会在全球范围内实现"严格使用"吗?

gra*_*eds 28 javascript strict

类似,但不一样,如何在全局范围内启用ECMAScript"use strict"?

我已经购买了JavaScript Patterns,它建议启用use strict.将它添加到二十几个javascript文件中会有点麻烦,所以在全局启用它会很好.我原本想要添加到我的main.js的顶部,如下所示:

"use strict" 
require({
    priority: ["jquery", "raphael", "myapp"] 
});
Run Code Online (Sandbox Code Playgroud)

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

<script data-main="lib/main" src="lib/require.js">"use strict"</script>
Run Code Online (Sandbox Code Playgroud)

其中任何一个都能在全局范围内启用ECMAScript 5严格模式吗?

T.J*_*der 42

TL; DR:

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

(另外,script在问题末尾重新标记:如果script元素具有a 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

在正常模式下,它会创建一个foo值为"bar" 的新全局变量并显示该"foo = bar"消息.在严格模式下,抛出异常,因为foo未定义.

如果我将此脚本标记放在页面中:

<script>
"use strict";
function test() {
    try {
      foo = "bar";
      display("foo = " + foo);
    }
    catch (e) {
      display("Exception: " + e);
    }
}
</script>
Run Code Online (Sandbox Code Playgroud)

...我按预期获得了异常(实例).如果我把它们放在单独的script标签中,但是:

<script>
"use strict";
</script>
<script>
function test() {
    try {
      foo = "bar";
      display("foo = " + foo);
    }
    catch (e) {
      display("Exception: " + e);
    }
}
</script>
Run Code Online (Sandbox Code Playgroud)

没有得到例外(在V8上)(例子).如果您考虑浏览器和JavaScript引擎的交互方式,这是合理的.

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

<script>
"use strict";
</script>
<script src="/inatoq"></script>
Run Code Online (Sandbox Code Playgroud)

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

请注意您的示例标记:

<script data-main="lib/main" src="lib/require.js">"use strict"</script>
Run Code Online (Sandbox Code Playgroud)

是无效的.一个script标签可能要么有一个src属性内容,但不能同时使用.(好吧,基本上; 这里的详细信息[HTML5]和这里 [HTML 4.01].)如果它有一个src元素,浏览器应该忽略内容,而大多数人都这样做.最.:-)

  • 我认为重要的是要提到语法代码单元通常组合成一个文件然后缩小为生产代码.这基本上全局应用严格模式,因为它现在是单个语法代码单元.这需要牢记在心,这就是像JSLint这样的工具不喜欢"使用严格"的原因;`在闭包之外. (3认同)

Jer*_*ell 8

JSLint突然报道:使用"use strict"的功能形式

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


}());
Run Code Online (Sandbox Code Playgroud)


BGe*_*sen 6

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

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

  • 你对上述内容有什么参考吗?显然有一种机制在起作用,虽然我不会说*"每个脚本标签......实际上都有自己的范围."*因为如果他们确实(他们自己的执行上下文)会弄乱`var`和函数声明.但显然有一些东西,如果你能指出我的话,我想更好地理解它.谢谢, (3认同)