41

ECMAScript5 中的严格模式编译指示有什么范围?

"use strict";

我想这样做(主要是因为 JSLint 不会抱怨):

"use strict";

(function () {
  // my stuff here...
}());

但我不确定这是否会破坏其他代码。我知道我可以做到这一点,这会将编译指示作用于函数......

(function () {

  "use strict";

  // my stuff here...

}());

但是 JSLint 抱怨它(当启用“严格”JSLint 选项时),因为它认为您在启用“使用严格”之前正在执行代码。

这是我的问题。如果我有 fileA.js:

"use strict";
// do some stuff

和fileB.js:

eval( somecodesnippet ); // disallowed by "use strict"

然后以相同的顺序将它们包含在我的 html 页面中,编译指示是否会被限定为文件,或者编译指示是否会溢出到 fileB 中,从而阻止 eval 执行?

4

4 回答 4

57

"use strict"仅适用于功能或程序范围。因此,如果您"use strict"在顶部有 fileA.js,则 fileA.js 以严格模式执行,并且其中定义的所有函数在调用时都会执行相同的操作。但是 fileB.js 是一个单独的程序,所以"use strict"from fileA.js 不适用于它——因此 fileB.js 将在非严格模式下执行。(当然,如果somecodesnippet"use strict"指令开头并正确解析,该代码将在严格模式下执行,并且由该代码定义的函数也将执行同样的操作。)严格性绝对不会“流血”——并且根据 ES5 4.2.2(诚然,非-规范,但我确信如果有必要我可以为此挖掘一个规范参考),“实现必须支持将不受限制和严格模式代码单元组合成一个复合程序”。

一个问题:如果您有时但并非总是在全局范围内使用严格模式,您就不能再将脚本连接到一个文件中。假设您按顺序有脚本 A、B、C、D。如果 A 是严格的,则整体串联将是严格的,即使 B/C/D 不是!相反,如果 A 不是严格的(并且是非空的),即使 B/C/D 是严格的,整体串联也将是非严格的。这已经影响了至少一个早期采用者的网站。

话虽如此,严格模式并不禁止eval. 当eval在严格模式下以正常方式调用时,使用形式的程序语法eval(code [, ...]),它是一个“直接” eval,其行为方式eval始终具有 - 除了code始终被评估为严格模式代码,即使code不以"use strict"指令开头,并且除了由代码创建的任何变量都保存在与任何现有变量分开的存储中。(确切的语义有点复杂;我在 Firefox 的 JavaScript 引擎上工作,最近才实现这些东西,即使在规范中花费了相当长的时间并致力于实现它对我来说仍然不直观。)

如果它不是这样调用的—— eval.call(...), setTimeout(eval, ...), setInterval(eval, ...), var ev = eval; ev(...);, 等等——它就是一个“间接”评估。间接 eval(无论是在严格模式内部还是外部)的行为略有不同:名称解析和变量定义就像在全局范围内一样发生。"use strict"(只有以指令开头的代码才会作为严格模式代码执行。)

严格模式支持在最新的Firefox nightlies中几乎 - 但不是完全 - 完成,因此可能值得下载一个来玩转已实现的严格模式的那些部分。我仍然会说在它完成之前推迟生产使用,但它肯定已经准备好进行实验(只要你了解严格模式还没有完全进入)。(至于 Sean McMillan 的链接,请注意,它声称的“支持”代表了每个项目符号所需的最低功能。严格模式测试要好得多,尽管要确保它们离完全覆盖严格模式还差得很远。 )

于 2010-10-08T10:58:51.950 回答
3

编辑看来我是不正确的。请参阅下面 Jeff Walden 的回答

查看相关问题的答案:“use strict”在 JavaScript 中做了什么,其背后的原因是什么?

尽管有 JSLint 的抱怨,但如果您只希望函数处于严格模式,则可以(并且应该)在函数内部使用。"use strict";如果您在全局上下文中使用它,那么它将强制您的所有代码处于严格模式。简短的回答:是的,它会阻止您使用eval.

于 2010-02-27T15:28:09.123 回答
0
eval( somecodesnippet ); // disallowed by "use strict"

如果您之前声明了一些代码片段,则不会。

var somecodesnippet = "你很棒的代码片段";

评估(一些代码片段);// 不被“use strict”禁止

于 2016-06-08T19:41:38.287 回答
0

整个文件:

<script...>
  "use strict";

或者

整个函数及其嵌入函数,例如:

function fn(){
  "use strict";
于 2018-01-12T14:08:57.967 回答