41

ECMAScript5 では、strict モード プラグマにはどのようなスコープがありますか?

"use strict";

私はこれをしたいと思います(主にJSLintがそれについて文句を言わないため):

"use strict";

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

しかし、それが他のコードを壊すかどうかはわかりません。私はこれを行うことができることを知っています。これにより、プラグマが関数にスコープされます...

(function () {

  "use strict";

  // my stuff here...

}());

しかし、JSLint は、「use strict」を有効にする前にコードを実行していると見なすため、(「strict」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 によると (確かに非-規範的ですが、必要に応じて規範的な参照を掘り下げることができると確信しています)、「実装は、無制限モードと厳密モードのコードユニットを単一の複合プログラムに組み合わせることをサポートする必要があります」.

これに関する 1 つの問題: グローバル スコープで厳密モードを使用する場合、常にではないが時々使用すると、スクリプトを 1 つのファイルに連結できなくなります。スクリプト A、B、C、D がこの順序であるとします。A が厳密な場合、B/C/D が厳密でなくても、全体的な連結は厳密になります! 逆に、A が正格でない (そして空でない) 場合、B/C/D が正格であっても、連結全体は非正格になります。これは、すでに少なくとも 1 つのアーリー アダプター サイトに影響を与えています。

とはいえ、strict モードは を禁止しませんevaleval形式のプログラム構文を使用して、厳密モードで通常の方法で呼び出された場合、これは、ディレクティブで始まらない場合でも、常に厳密モード コードとして評価されることを除いて、常に同じeval(code [, ...])ように動作する「直接的な」評価です。ただし、コードによって作成された変数は、既存の変数とは別のストレージに保持されます。(正確なセマンティクスは少し複雑です。私は Firefox の JavaScript エンジンに取り組んでおり、最近ではこの機能を実装していますが、仕様にかなりの時間を費やして実装に取り​​組んだ後でも、まだ直感的ではありません。)evalcodecode"use strict"

そのように呼び出されない場合 -- eval.call(...)setTimeout(eval, ...)setInterval(eval, ...)var ev = eval; ev(...);など -- 「間接的な」評価です。間接評価 (厳密モードの内側または外側に関係なく) は少し異なる動作をします。名前解決と変数定義は、あたかもグローバル スコープ内にあるかのように行われます。"use strict"(コードは、ディレクティブで始まる場合にのみ厳密モード コードとして実行されます。)

Strict モードのサポートは、最新のFirefox nightliesでほぼ終了していますが、完全ではありません。完成するまで本番環境での使用は控えるべきだと思いますが、実験の準備ができていることは間違いありません (厳密モードがまだ完全に実装されていないことを理解している限り)。(Sean McMillan のリンクについては、その「サポート」の主張が、各弾丸に必要な機能の極端な最小値を表していることに注意してください。厳密モードのテストは、厳密モードを完全にカバーするにはほど遠いことを確認してはいますが、はるかに優れています。 )

于 2010-10-08T10:58:51.950 に答える
3

編集私は間違っていたようです。以下の Jeff Walden の回答をご覧ください。

関連する質問に対するこの回答を確認してください: JavaScript で "use strict" は何を行い、その背後にある理由は何ですか?

JSLint の不満にもかかわらず、関数を厳密モードにしたい場合は、関数内で使用できます (使用する必要があります) "use strict";グローバル コンテキストで使用すると、すべてのコードが強制的に厳密モードになります。簡単な答え:はい、 の使用がブロックされますeval

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

前に somecodesnippet を宣言した場合ではありません。

var somecodesnippet = "あなたのすばらしいコードニペットはこちら";

eval( somecodesnippet ); // 「use strict」では許可されません

于 2016-06-08T19:41:38.287 に答える