在 ECMAScript5 中,“use strict”的范围是什么?
ECMAScript5 中严格模式编译指示的范围是什么?
"use strict";
我想这样做(主要是因为 JSLint 不会抱怨它):
"use strict";
(function () {
// my stuff here...
}());
但我不确定这是否会破坏其他代码。我知道我可以这样做,这会将编译指示的范围限制到函数...
(function () {
"use strict";
// my stuff here...
}());
但是 JSLint 抱怨它(当启用“strict”JSLint 选项时),因为它认为您在启用“use strict”之前正在执行代码。
这是我的问题。如果我有 fileA.js:
"use strict";
// do some stuff
和 fileB.js:,
eval( somecodesnippet ); // disallowed by "use strict"
然后以相同的顺序将它们包含在我的 html 页面中,那么编译指示的范围是否会限定在文件中,或者编译指示是否会渗透到 fileB 中,从而阻止 eval 执行?
What scope does the strict mode pragma have in ECMAScript5?
"use strict";
I'd like to do this (mainly because JSLint doesn't complain about it):
"use strict";
(function () {
// my stuff here...
}());
But I'm not sure if that would break other code or not. I know that I can do this, which will scope the pragma to the function...
(function () {
"use strict";
// my stuff here...
}());
but JSLint complains about it (when the "strict" JSLint option is enabled) because it thinks you're executing code before you enable "use strict".
Here's my question. If I have fileA.js:
"use strict";
// do some stuff
and fileB.js:
eval( somecodesnippet ); // disallowed by "use strict"
and then include them in my html page in that same order, will the pragma be scoped to the file, or will the pragma bleed over into fileB, thus blocking the eval execution?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
“use strict”
仅适用于函数或程序范围。因此,如果 fileA.js 的顶部带有"use strict"
,则 fileA.js 将以严格模式执行,并且其中定义的所有函数在调用时都会执行相同的操作。但 fileB.js 是一个单独的程序,因此 fileA.js 中的“use strict”
不适用于它 - 因此 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 的链接,请注意,它的“支持”声明代表了每个项目符号所需的最低限度的功能。严格模式测试要好得多,尽管要确保它们远未完全覆盖严格模式。 )
"use strict"
applies only to function or program scope. So if you have fileA.js with"use strict"
at the top, fileA.js executes in strict mode, and all functions defined in it will do the same when called. But fileB.js is a separate program, so the"use strict"
from fileA.js doesn't apply to it -- and therefore fileB.js will execute in non-strict mode. (Of course, ifsomecodesnippet
begins with a"use strict"
directive and parses properly, that code will execute in strict mode, and functions defined by that code will do likewise.) Strictness absolutely does not "bleed" -- and per ES5 4.2.2 (admittedly non-normative, but I'm sure I could dig up a normative reference for this if necessary), "an implementation must support the combination of unrestricted and strict mode code units into a single composite program".One gotcha of this: if you use strict mode in the global scope sometimes but not always, you can no longer concatenate your scripts into a single file. Suppose you have scripts A, B, C, D in that order. If A is strict, the overall concatenation will be strict, even if B/C/D weren't! Conversely, if A isn't strict (and is non-empty), the overall concatenation will be non-strict, even if B/C/D were strict. This has already bitten at least one early-adopter site out there.
All that said, strict mode does not forbid
eval
. Wheneval
is called the normal way in strict mode, using program syntax of the formeval(code [, ...])
, it's a "direct" eval which behaves the wayeval
always has -- except thatcode
is always evaluated as strict mode code, even ifcode
doesn't start with a"use strict"
directive, and except that any variables created by the code are kept in their own separate storage from any existing variables. (The exact semantics are a bit complicated; I work on Firefox's JavaScript engine, of late implementing this stuff, and even after a fair amount of time in the spec and working on an implementation it's still not intuitive to me.)If it's not called that way --
eval.call(...)
,setTimeout(eval, ...)
,setInterval(eval, ...)
,var ev = eval; ev(...);
, and so on -- it's an "indirect" eval. Indirect eval (whether inside or outside strict mode) behaves a little differently: name resolution and variable definition occur as though in the global scope. (The code will execute as strict mode code only if it begins with a"use strict"
directive.)Strict mode support is nearly -- but not completely -- finished in the latest Firefox nightlies, so it may be worth downloading one to play around with those parts of strict mode which are implemented. I'd still say hold off on production use until it's complete, but it's definitely ready for experimentation (so long as you understand strict mode isn't fully in yet). (As for Sean McMillan's link, be aware that its claims of "support" represent the extreme minimum of functionality needed for each bullet. The strict mode tests are much better, although to be sure they're nowhere close to covering strict mode completely.)
编辑看来我错了。请参阅下面Jeff Walden 的回答。
查看相关问题的答案:“use strict”在 JavaScript 中做什么,其背后的原因是什么?
尽管 JSLint 抱怨,您可以(并且应该)使用 <如果您只想让函数处于严格模式,则在函数内部使用 code>"use strict"; 。如果您在全局上下文中使用它,那么它将强制您的所有代码处于严格模式。 简短回答:是的,它会阻止您使用
eval
。EDIT It appears I was incorrect. Please see Jeff Walden's answer below.
Check out this answer to a related question: What does "use strict" do in JavaScript, and what is the reasoning behind it?
Despite JSLint's complaints, you can (and should) use
"use strict";
inside of a function if you only want that function to be in strict mode. If you use it in the global context then it will force all your code to be in strict mode. Short answer: yes, it will block your use ofeval
.如果您之前声明了 somecodesnippet,则不会。
Not if you declare somecodesnippet before.
整个文件:
或
整个函数及其嵌入函数
例如 :
The entire file :
or
The entire function and its embeded functions
for example :