を使用'use strict';
しても、コードが突然改善されるわけではありません。
JavaScriptのstrictモードでの機能ですECMAScriptの5。strictモードを有効にするには、スクリプト/関数の上部でこれを宣言します。
'use strict';
JavaScriptエンジンがこのディレクティブを検出すると、特別なモードでコードを解釈し始めます。このモードでは、潜在的なバグになる可能性のある特定のコーディングプラクティスが検出されると、エラーがスローされます(厳密モードの背後にある理由です)。
この例を考えてみましょう:
var a = 365;
var b = 030;
数値リテラルを揃えるという執念の中で、開発者は不注意にb
8進リテラルで変数を初期化しました。非厳密モードは、これを24
(base 10の)値を持つ数値リテラルとして解釈します。ただし、strictモードではエラーがスローされます。
ストリクトモードの専門分野の完全ではないリストについては、この回答を参照してください。
どこで使用すればよい'use strict';
ですか?
私の新しい JavaScriptアプリケーションでは:絶対に!厳格モードは、コードで愚かなことをしているときに内部告発者として使用できます。
私の既存の JavaScriptコードでは:おそらくそうではありません!既存のJavaScriptコードにストリクトモードで禁止されているステートメントがある場合、アプリケーションは単純に中断します。ストリクトモードが必要な場合は、既存のコードをデバッグして修正する準備をする必要があります。これが、使用'use strict';
してもコードが突然改善されない理由です。
strictモードを使用するにはどうすればよいですか?
'use strict';
スクリプトの上にステートメントを挿入します。
// File: myscript.js
'use strict';
var a = 2;
....
ファイル内のすべてがmyscript.js
厳密モードで解釈されることに注意してください。
または、'use strict';
関数本体の上にステートメントを挿入します。
function doSomething() {
'use strict';
...
}
関数の字句スコープ内のすべてがdoSomething
厳密モードで解釈されます。ここでは語彙スコープという言葉が重要です。たとえば、厳格なコードが厳格ではないライブラリの関数を呼び出す場合、コードのみが厳格モードで実行され、呼び出された関数は実行されません。詳細な説明については、この回答を参照してください。
ストリクトモードで禁止されていることは何ですか?
厳格モードで禁止されているいくつかのことを説明する素晴らしい記事を見つけました(これは排他的なリストではないことに注意してください):
範囲
これまで、JavaScriptは関数のスコープについて混乱してきました。静的スコープのように見える場合もありますが、一部の機能は動的スコープのように動作させます。これは混乱を招き、プログラムの読み取りと理解を困難にします。誤解はバグの原因になります。また、パフォーマンスの問題でもあります。静的スコープを使用すると、コンパイル時に変数バインディングを実行できますが、動的スコープの要件により、バインディングをランタイムに延期する必要があるため、パフォーマンスが大幅に低下します。
厳格モードでは、すべての変数バインディングを静的に行う必要があります。つまり、以前は動的バインディングが必要であった機能を削除または変更する必要があります。具体的には、withステートメントが削除され、呼び出し元の環境を改ざんするeval関数の機能が大幅に制限されています。
厳格なコードの利点の1つは、YUI Compressorなどのツールが
処理するときに、より優れた処理を実行できることです。
暗黙のグローバル変数
JavaScriptにはグローバル変数が含まれています。変数を明示的に宣言しない場合、グローバル変数が暗黙的に宣言されます。これにより、初心者は基本的な家事の一部を無視できるため、プログラミングが簡単になります。しかし、それは大規模なプログラムの管理をはるかに困難にし、信頼性を著しく低下させます。したがって、厳密モードでは、暗黙のグローバル変数は作成されなくなりました。すべての変数を明示的に宣言する必要があります。
グローバルリーク
this
グローバルオブジェクトにバインドされる原因となる状況は多数あります。たとえばnew
、コンストラクター関数を呼び出すときにプレフィックスを指定し忘れた場合、コンストラクターthis
は予期せずグローバルオブジェクトにバインドされるため、新しいオブジェクトを初期化する代わりに、グローバル変数を静かに改ざんします。これらの状況では、ストリクトモードは代わりににバインドthis
しますundefined
。これにより、コンストラクターが代わりに例外をスローし、エラーをより早く検出できるようになります。
騒々しい失敗
JavaScriptには常に読み取り専用のプロパティがありましたが、ES5のObject.createProperty
関数がその機能を公開するまで自分で作成することはできませんでした。読み取り専用プロパティに値を割り当てようとすると、警告なしに失敗します。割り当てによってプロパティの値が変更されることはありませんが、プログラムはそのように処理されます。これは、プログラムが不整合な状態になる可能性がある完全性の危険です。厳密モードでは、読み取り専用プロパティを変更しようとすると、例外がスローされます。
オクタル
ワードサイズが3の倍数であるマシンでマシンレベルのプログラミングを行う場合、数値の8進数(または8を基数とする)表現は非常に役立ちました。CDC6600メインフレーム(ワードサイズが60ビット)で作業する場合、8進数が必要でした。8進数を読むことができれば、単語を20桁で見ることができます。2桁はオペコードを表し、1桁は8つのレジスタの1つを識別しました。マシンコードから高級言語へのゆっくりとした移行の間に、プログラミング言語で8進形式を提供することは有用であると考えられました。
Cでは、非常に残念な8進数表現が選択されました。先行ゼロです。したがって、Cでは、0100
100ではなく64を意味し、08
8ではなくエラーを意味します。さらに残念なことに、この時代錯誤は、JavaScriptを含むほとんどすべての現代の言語にコピーされており、エラーの作成にのみ使用されます。他の目的はありません。したがって、厳密モードでは、8進形式は許可されなくなりました。
等
引数の疑似配列は、ES5の配列に少し似ています。厳密モードでは、その
プロパティcallee
とcaller
プロパティが失われます。これによりarguments
、多くの機密コンテキストをあきらめることなく、信頼できないコードに渡すことができます。また、arguments
関数の
プロパティが削除されます。
厳密モードでは、関数リテラルの重複キーは構文エラーを生成します。関数に同じ名前の2つのパラメーターを含めることはできません。関数は、パラメーターの1つと同じ名前の変数を持つことはできません。関数はdelete
それ自身の変数を持つことはできません。delete
設定不可能なプロパティへの試み
は例外を投げるようになりました。プリミティブ値は暗黙的にラップされません。
将来のJavaScriptバージョンの予約語
ECMAScript 5は予約語のリストを追加します。これらを変数または引数として使用すると、strictモードはエラーをスローします。予約語は次のとおりです。
implements
、interface
、let
、package
、private
、protected
、public
、static
、およびyield
参考文献