ホームページ > ウェブフロントエンド > jsチュートリアル > JavaScript 厳密モード (Strict Mode) の深い理解_JavaScript スキル

JavaScript 厳密モード (Strict Mode) の深い理解_JavaScript スキル

WBOY
リリース: 2016-05-16 16:29:52
オリジナル
1585 人が閲覧しました

ECMAScript5 で導入された厳密モードにより、JavaScript ランタイム環境が開発プロセスで最も一般的で見つけにくいエラーの一部を現在とは異なる方法で処理できるようになるため、開発者は「より良い」JavaScript 言語を使用できるようになります。厳密モードをサポートしているのは Firefox だけだったので、私は長い間、このモードについて懐疑的でした。しかし現在、すべての主要なブラウザが最新バージョン (IE10、Opera12、Android4、IOS5 を含む) でストリクト モードをサポートするようになりました。

厳密モードはどのような役割を果たしますか?

厳密モードでは JavaScript に多くの変更が加えられますが、私はそれらを 2 つのカテゴリ (明らかな変更と微妙な変更) に分類します。小規模な改善の目的は、現在の JavaScript のいくつかの詳細な問題を修正することですが、ここでは詳しく説明しません。興味がある場合は、Dmitry Soshnikov による優れた文書 ECMA-262-5 の第 2 章 Strict Mode を参照してください。 。 ここでは、厳密モードによって導入される明らかな変更、厳密モードを使用する前に知っておくべき概念、および最も役立つ変更に焦点を当てます。

特定の機能の学習を開始する前に、厳密モードの目的の 1 つは、デバッグをより速く、より便利に行えるようにすることであることを思い出してください。ランタイム環境にとっては、(厳密モードを有効にしていない JavaScript ランタイム環境でよくあることですが) 黙って失敗したり、奇妙な動作をしたりするよりも、問題を検出したときに明示的にエラーをスローする方が良いです。厳密モードではより多くのエラーがスローされますが、これらのエラーが注意を呼び、以前は見つけるのが難しかった多くの潜在的な問題が修正されるため、これは良いことです。

キーワードを使用して削除

まず、with ステートメントが strict モードから削除されます。with ステートメントを含むコードは、strict モードで例外をスローします。したがって、厳密モードを使用するための最初のステップは、コード内で with を使用しないようにすることです。

コードをコピーします コードは次のとおりです:

// 次の JavaScript コードは、厳密モードでエラーをスローします
with (場所) {
アラート(href);
}

グローバル変数の誤った割り当てを防止します

次に、値を割り当てる前にローカル変数を宣言する必要があります。厳密モードが有効になる前に、宣言されていないローカル変数をコピーすると、同じ名前のグローバル変数が自動的に作成されます。これは Javascript プログラムで最も一般的なエラーの 1 つであり、これを厳密モードで実行しようとすると、明示的な例外がスローされます。

コードをコピーします コードは次のとおりです:

// 厳密モードでは例外がスローされます
(関数() {
SomeUndeclaredVar = "foo";
}());

関数内の THIS はデフォルトでグローバルを指さなくなりました

厳密モードでのもう 1 つの重要な変更は、未定義または空 (null または未定義) の関数内の this がデフォルトでグローバル環境 (global) を指さなくなったことです。これにより、次のような関数のデフォルトの this 動作に依存する一部のコードの実行でエラーが発生します。

コードをコピーします コードは次のとおりです:
window.color = "赤";
関数sayColor() {
アラート(this.color);
}
// 厳密モードではエラーが報告されます。厳密モードでない場合は、「red」
が表示されます。 SayColor();
// 厳密モードではエラーが報告されます。厳密モードでない場合は、「red」
が表示されます。 SayColor.call(null);

これは割り当てられるまで未定義のままです。つまり、コンストラクターの実行時に、前に明確な新しいキーワードが存在しない場合、例外がスローされます。

コードをコピーします コードは次のとおりです:
関数 人(名前) {
This.name = 名前;
}
//厳密モードではエラーが報告されます
var me = 人("ニコラス");

上記のコードでは、パーソン コンストラクターが実行されると、前に new がないため、関数内の this は未定義のままになります。未定義のプロパティを設定できないため、上記のコードはエラーをスローします。 非厳密モード環境では、コピーされない this はデフォルトで window グローバル変数を指し、操作の結果、window グローバル変数の name 属性が誤って設定されてしまいます。

名前の重複を防止します

大量のコードを記述する場合、オブジェクトのプロパティと関数のパラメーターを誤って重複した名前に設定してしまうことがよくあります。この場合、厳密モードでは明示的にエラーがスローされます

コードをコピー コードは次のとおりです:

//変数名が重複すると、厳密モードではエラーが報告されます
function doSomething(value1, value2, value1) {
//コード
}
// オブジェクト属性名が重複すると、厳密モードではエラーが報告されます:
var オブジェクト = {
foo: "バー"、
foo: 「バズ」
};

上記のコードは、厳密モードでは構文エラーとみなされ、実行前にプロンプ​​トが表示されます。

安全な EVAL()

eval() ステートメントは最終的には削除されませんでしたが、厳密モードでは依然としていくつかの改善が加えられました。最大の変更点は、 eval() で実行される変数および関数の宣言が、現在のスコープ内に対応する変数または関数を直接作成しないことです。次に例を示します。

コードをコピーします コードは次のとおりです:

(関数() {
eval("var x = 10;");
// 非厳密モードでは、アラート 10
// 厳密モードでは、x が定義されていないため、例外がスローされます。
アラート(x);
}());

eval() の実行中に作成された変数または関数はすべて eval() に保持されます。ただし、eval() ステートメントの戻り値から、eval() の実行結果を明確に取得できます。例:

コードをコピーします コードは次のとおりです:

(関数() {
var result = eval("var x = 10, y = 20; x y");
//残りのステートメントは、厳密モードまたは非厳密モードで正しく実行できます (結果は 30)
。 アラート(結果);
}());

読み取り専用プロパティを変更するときに例外がスローされました

ECMAScript5 では、オブジェクトの特定のプロパティを読み取り専用に設定したり、オブジェクト全体を変更不能にしたりする機能も導入されています。 ただし、非厳密モードでは、読み取り専用プロパティを変更しようとするとエラーが表示されずに失敗します。 一部のブラウザーのネイティブ API を処理しているときに、この状況が発生する可能性があります。この場合、厳密モードでは明示的に例外がスローされ、このプロパティの変更が許可されていないことが通知されます。

コードをコピーします コードは次のとおりです:

var person = {};
Object.defineProperty(人, "名前" {
書き込み可能: false、
値: 「ニコラス」
});
// 非厳密モードではサイレント障害が発生し、厳密モードでは例外がスローされます。 person.name = "ジョン";

上記の例では、name 属性は読み取り専用に設定されており、非厳密モードで name 属性を変更してもエラーは発生しませんが、変更は成功しません。ただし、厳密モードでは明示的に例外がスローされます。

注: ECMAScript プロパティ属性仕様を使用する場合は、厳密モードを有効にすることを強くお勧めします。

使い方は?

最新のブラウザで厳密モードをオンにするのは非常に簡単です。JavaScript コードに次のコマンドを入力するだけです

「厳密に使用する」;


上記のコードは変数に割り当てられていない単なる文字列であるように見えますが、実際には JavaScript エンジンに厳密モードに切り替えるよう指示しています (厳密モードをサポートしていないブラウザは上記のコードを無視し、何も実行しません)その後の実行への影響)。このディレクティブはグローバルまたは特定の関数に適用できますが、グローバル環境では厳密モードを有効にしないように注意する必要があります。

コードをコピーします コードは次のとおりです:
// このように使用しないでください
"厳密な使用";
関数 doSomething() {
// コードのこの部分は厳密モードで実行されます
}
関数 doSomethingElse() {
// コードのこの部分は、厳密モードでも実行されます
}


上記のコードは大きな問題ではないようですが。ただし、ページに紹介されているすべてのコードを保守する責任がない場合、この方法で厳密モードを使用すると、厳密モード用に準備されていないサードパーティのコードによって引き起こされる問題にさらされることになります。
したがって、関数内で厳密モードを有効にする命令を適用するのが最善です。例:

コードをコピー コードは次のとおりです:

関数 doSomething() {
"厳密な使用";
//この関数のコードは厳密モードで実行されます
}
関数 doSomethingElse() {
//この関数のコードは厳密モードでは実行されません
}


複数の関数で厳密モードを有効にしたい場合は、即時呼び出し関数式 (IIFE) を使用します:

コードをコピーします コードは次のとおりです:

(関数() {
"厳密な使用";
関数 doSomething() {
// この関数は厳密モードで実行されます
}
関数 doSomethingElse() {
// この関数は厳密モードでも実行されます
}
}());

結論

今後は JavaScript 厳密モードを有効にすることを強くお勧めします。これにより、コード内の気付かないエラーを見つけることができます。グローバルに有効にしないでください。ただし、IIFE (関数式の即時実行) を可能な限り使用して、複数の関数スコープに厳密モードを適用できます。最初は、これまでに見たことのないエラー メッセージが表示されますが、これは正常な現象です。厳密モードを有効にする場合は、サポートされているブラウザで必ずテストして、新たな潜在的な問題を特定してください。コードに「use strict」行を追加するだけで、コードの残りの部分が機能すると想定しないでください。最後に、厳密モードでより適切なコードの作成を開始します。

注:
以下は、さまざまなブラウザーでの厳密モードのサポートの概要です。
このページでは、現在のブラウザーの厳密モードのサポートをテストできます。

厳密モードの利点:

JavaScript を強化する
1. これはカプセル化されなくなりました。通常モードでは、これは常にオブジェクトです。
2. Fun.caller および fun.arguments は削除できる属性ではなく、設定または取得もできません。
3. Arguments.caller も削除できない属性であり、設定や取得もできません。

将来の ECMAScript バージョンへの道を開く
1. 次の予約語が追加されました:implements、interface、let、package、private、protected、public、static、および yield。
2. メソッド宣言は、if や for などのステートメントの途中ではなく、スクリプトまたはメソッドの先頭に配置する必要があります。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート