JavaScript厳格モード

ECMAScriptの第5版では、 厳密モード (以降、厳密モードと呼びます)が導入されました。 Strict ModeはJavaScriptに制限の層を課し、言語の危険な部分(歴史的には存在するが存在しない方がよい部分)から保護し、エラーの可能性を減らします。



この記事を読みながら、ES5仕様で宣言されているすべての厳格モードルールをカバーする38のテストを作成しました。 ここで 、ブラウザがこれらの管理をサポートする方法を確認できます







各テストのコードは、仕様の理解を深めるために記事の最後に記載されています。 コードをコンソールにコピーして、テストを手動で実行することもできます。 すべてのソースコードはリポジトリにあります



Firefox 4はすでに完全モードを完全にサポートしており、Chrome 11はほぼ完全にサポートされています。 ストリクトモードがすぐ近くにあります。さらに詳しく見てみましょう。



ストリクトモードを有効にする方法



JavaScriptコードの先頭に"use strict"



を追加すると、厳格モードがコード全体に適用されます。

 "use strict"; 012; //  .   SyntaxError  Strict Mode
      
      





または、関数本体の先頭に"use strict"



を追加することにより、個別の関数でのみ厳密モードを有効にできます。

 012; //  (Strict Mode   ) function foo() { "use strict"; x=3; //Strict Mode   -      } foo(); //ReferenceError (Strict Mode   )
      
      







厳格モードの内部関数は外部関数を継承しますか?



厳密モードが有効になっている外部関数内で宣言された内部関数も、厳密モードになります。

 var wrapper = function(fn) { 'use strict'; var deleteNonConfigurable = function () { var obj = {}; Object.defineProperty(obj, "name", { configurable: false }); delete obj.name; //   TypeError  Strict Mode } return deleteNonConfigurable; } wrapper()(); //TypeError (Strict Mode )
      
      





厳密モードは、厳密関数内で実行される「非厳密」(元の非厳密)関数には適用されないことに注意することが重要です(関数として引数として送信されるか、callまたはapplyを使用して実行されます)。

 var test = function(fn) { 'use strict'; fn(); } var deleteNonConfigurable = function () { var obj = {}; Object.defineProperty(obj, "name", { configurable: false }); delete obj.name; //   TypeError  Strict Mode } test(deleteNonConfigurable); //  (Strict Mode  )
      
      





ブラウザコンソールで厳格モードを有効にできないのはなぜですか?



ファイアウォールコンソールまたは他のコンソールでコードを実行するとき、関数の外側で"use strict"



することは無効です。 これは、ほとんどのコンソールがevalでコードをフレーム化するため、 "use strict"



最初の式で"use strict"



ないためです。 これを回避するには、コードをクロージャー(IIFE)でラップします。最初に"use strict"



(ただし、厳密モードを有効にするこの方法をテストしたとき、特にwebkit開発者ツールコンソールで作業している場合、ページでコードをテストする方が良い):

 (function() { "use strict"; var a; var b; function bar() { x = 5; //Strict Mode        } bar(); // ReferenceError (Strict Mode ) })();
      
      





ブラウザがストリクトモードをサポートしていない場合はどうなりますか?



なし。 "use strict"



ディレクティブは、厳密モードをサポートしないすべてのJavaScriptエンジンによって無視される正規の文字列式です。 これにより、すべてのブラウザーでStrict Mode構文を問題なく使用できますが、Strict Modeをサポートするブラウザーはそれを使用します。



ストリクトモードに含まれるルールは何ですか?



ルールは厳格モード仕様で定義されており、「コンパイル」および解釈(スクリプトの実行)中に制限が含まれています。 これは入門的な概要です(次の段落で例を挙げて各ルールを説明しました): ecma262-5.com/ELS5_HTML.htm#Annex_C



構文エラー


ほとんどの場合、ストリクトモードは、ブートプロセス中に疑わしいコードまたは違法なコードの実行を防ぎます。 8進数、重複する変数名、deleteの誤った使用、evalおよびargumentsキーワードでこのようなことを試みると、withを使用するとSyntaxErrorがスローされます。



この言葉


厳格モードでは、このオブジェクトは調整されません。 これはおそらく、厳格モードの最も興味深い部分であり、開発者にとって最も難しい(衝撃的な)部分です。 呼び出しまたは適用する最初の引数がnullまたは未定義の場合、この関数の値はグローバルオブジェクトに変換されます(ブラウザの場合、これはウィンドウです)。



グローバル変数の直接作成


誰もがこれに同意するわけではありませんが、間接的にグローバルオブジェクトを作成することはほとんどの場合間違いです。 厳格モードでは、レッドカードReferenceErrorが与えられます。



arguments.callerおよびarguments.callee


これらの「有用なプロパティ」(それらを使用したことのないレーンから)は、厳密モードでは禁止されています。 コードでそれらを使用すると、厳格モードは例外をスローします。



既存のオブジェクト名を宣言する


2つの同一のキーを持つオブジェクトを作成すると、厳格モードはTypeError例外をスローします。



テスト



これが私の厳格モードテストのソースです。 各テストスイートには、テスト中のECMAScript仕様の一部を参照するコメントがあります。 このバージョンは、「コンソールモード」で実行できます。 つまり テストをコピーし、コンソールに貼り付けて、変更せずに実行できます。 HTMLモードで動作する同じコードを使用してテストページを作成しました。テストページは記事の冒頭で紹介しました。 このソースには、私のgithubリポジトリに追加のオブジェクトがあります 。 エラーがいくつかあるはずです-エラーを送信してください!



翻訳者から:ここの記事には膨大なコードがあり、それをペーストビンに投げました



おわりに



コードを改善するために一部の言語機能へのアクセスを禁止することは重要なポイントです。この議論を先送りしましょう。 厳密モードを守るために、これは完全な変更(後方互換性を損なう)と何もしない(言語を混乱させ、開発者に悪いことを教える)ことの間の大きな妥協だと言いたいです。



他に読むもの



ECMA-262 5th Edition: ECMAScriptの厳格モード

Asen Bozhilov: 厳格なテスター

ECMAScript 5互換性チャート、 厳格モードパート 。 これは優れたソースであり、Yuri Zaitsev(Juriy Zaytsev別名「kangax」)によって開発された大きな互換性テーブルの一部です。



翻訳者から。 厳格なモードは、優れた制限と一般的なエラーに対する耐性を除いて、すべてのブラウザーのほぼ半分でサポートされていますが、厳格なモードには他の利点もあります (記事mraleph )。 すぐに、厳密モードを使用しないと、不正な形式になります( requestAnimationFrame vs setTimeoutに似ています )。 今こそ実験を開始する時です!



All Articles