在ECMAScript5中,"使用严格"的范围是什么?

spu*_*dly 41 javascript scope strict ecma262 ecmascript-5

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

"use strict";
Run Code Online (Sandbox Code Playgroud)

我想这样做(主要是因为JSLint没有抱怨它):

"use strict";

(function () {
  // my stuff here...
}());
Run Code Online (Sandbox Code Playgroud)

但我不确定这是否会破坏其他代码.我知道我可以做到这一点,这将把pragma的范围扩展到函数...

(function () {

  "use strict";

  // my stuff here...

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

但JSLint抱怨它(当启用"严格"JSLint选项时),因为它认为您在启用"use strict"之前正在执行代码.

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

"use strict";
// do some stuff
Run Code Online (Sandbox Code Playgroud)

和fileB.js:

eval( somecodesnippet ); // disallowed by "use strict"
Run Code Online (Sandbox Code Playgroud)

然后将它们以相同的顺序包含在我的html页面中,将pragma限定为文件,还是将pragma放到fileB中,从而阻止eval执行?

Jef*_*den 55

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

其中一个问题是:如果您有时但不总是在全局范围内使用严格模式,则无法再将脚本连接到单个文件中.假设您按顺序拥有脚本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.间接eval(无论是在严格模式内部还是外部)的行为略有不同:名称解析和变量定义就像在全局范围内一样.(只有当代码以"use strict"指令开头时,代码才会作为严格模式代码执行.)

严格模式的支持几乎是-但不完全-完成了在最新的Firefox Nightlies版,因此它可能是值得下载一个玩弄它实现的严格模式的部分.我还是要说推迟生产使用,直到它的完整,但它绝对准备好实验(只要你理解严格模式没有完全还).(至于肖恩·麦克米兰的链接,要知道,它的"支持"索赔代表所需要的每发子弹的功能极端最低.严格的模式测试是好多了,但可以肯定他们是无处接近完全覆盖严格模式. )

  • "严格绝对没有"流血" - 这不完全正确.当您使用它的函数在严格模式下定义时,不能在非严格代码中使用`.caller`.因此,非严格的代码实际上可以因为其他代码处于严格模式而中断 - 我会考虑出血. (4认同)

nto*_*end 3

编辑看来我错了。请参阅下面 Jeff Walden 的回答

查看相关问题的答案:What does "use strict" do in JavaScript, and is the Reasoning Behind it?

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

  • 这个答案是不正确的。使用“fileA.js”顶部的指令会导致整个文件处于严格模式,但不会导致“fileB.js”处于严格模式,无论它们在 HTML 页面中包含的顺序如何。此外,“eval()”在严格模式下的工作方式有所不同,但它仍然有效。它没有被“阻止”。 (3认同)