javascript厳格モードを深く理解する(Strict Mode)

6044 ワード

ECMAScript 5に導入された厳格なモードは、JavaScriptの実行環境をいくつかの開発過程で最も一般的で発見しにくいエラーに対して現在とは違った処理をすることによって、開発者により「より良い」JavaScript言語を持たせる.長い間、厳しいモードをサポートしているのはFirefoxだけです.厳しいモードに対して疑いを持っていました.しかし、今日になって、すべての主流のブラウザは彼らの最新バージョンで厳格なモード(IE 10、Opera 12、Android 4、IOS 5を含む)をサポートしています.
厳格なモードはどんな効果がありますか?
厳格なモードはJavaScriptのために多くの変化を導入しています.彼らを二つの種類に分けます.細かい改善の目標は現在のJavaScriptの細部問題を修復することです.これらの問題についてはここで詳しく紹介しません.興味があれば、Dmitry Soshnikovの素晴らしい文書ECMA-626-5 in Detail Chapter 2 Strict Modeを読んでください.ここでは主に厳格なモードで導入された明らかな変化を紹介します.それらは厳格なモードを使う前に知っておくべき概念とあなたにとって最大の変化を助けます.
具体的な特性を学ぶ前に、厳格なモードの大きな目標はより速くて便利なデバッグになることを覚えてください.運行環境は問題が発見された時に表示的にエラーを出すのは黙っている失敗や奇異な行動(厳格なモードを開けていないJavaScript運行環境はよくこのようにする)より良いです.厳格なモードはもっと多くのエラーを投げますが、これはいいことです.これらのエラーがあなたを喚起し、多くの以前に発見されにくい潜在的な問題を修復します.
WITHキーワードの削除
まず、厳格モードではwith文が削除され、with文を含むコードは厳格モードで異常を投げます.厳格なモードを使用するための第一歩:あなたのコードにwithが使用されていないことを確認します.
 
  
// JavaScript
with (location) {
    alert(href);
}
予期せぬグローバル変数の割り当てを防ぐ
第二に、局部変数は賦課前に先に説明しなければならない.厳密なモードを有効にする前に、未説明のローカル変数をコピーすると、自動的に同じ名前のグローバル変数が作成されます.これはJavacriptプログラムの中で最も発生しやすいエラーの一つです.厳格なモードで試してみると、顕著な例外が出てきます.
 
  
//
(function() {
    someUndeclaredVar = "foo";
}());
関数のTHISは、デフォルトではグローバルに向けられません.
厳密モードにおけるもう一つの重要な変化は、関数において定義されていないか、または空(null or undefined)であるthisが、デフォルトではグローバル環境(global)に向けられていないことである.これはいくつかの依存関数のデフォルトのthis挙動のコード実行エラーをもたらします.例えば、
 
  
window.color = "red";
function sayColor() {
    alert(this.color);
}
// strict , “red"
sayColor();
// strict , “red"
sayColor.call(null);
thisは、与えられる前にundefinedとして維持されます.これは、構造関数が実行される時に、以前に明確なnewキーワードがなかったら、異常を投げかけることを意味します.
 
  
function Person(name) {
    this.name = name;
}
//
var me = Person("Nicholas");
上のコードの中で、Personコンストラクタは以前はnewがなかったため、関数の中のthisはundefinedとして保存されます.undefinedの属性を設定できないため、上のコードは間違っています.非strictモードの環境では、コピーされていないthisはWindowsのグローバル変数をデフォルトで指し、実行の結果は予期せぬwindowグローバル変数のためにname属性を設定します.
重名を防ぐ
大量のコードを作成すると、オブジェクト属性と関数パラメータが重複した名前に設定されやすくなります.厳格モードはこの場合に明らかにエラーを出すことができます.
 
  
// ,
function doSomething(value1, value2, value1) {
    //code
}
// , :
var object = {
    foo: "bar",
    foo: "baz"
};
以上のコードは厳格なモードでは文法エラーと見なされます.実行前にヒントを与えられます.
安全なEVAL()
eval()の文は最終的に削除されませんでしたが、厳密なモードではいくつかの改良がされています.最大の変更は、eval()において実行される変数と関数の説明であり、現在の作用領域に直接に対応する変数または関数を作成しないことである.
 
  
(function() {
    eval("var x = 10;");
    // ,alert 10
    // x ,
    alert(x);
}());
eval()実行中に作成された変数または関数は、eval()に保持されます.ただし、eval()文の戻り値からeval()中の実行結果を明確に取得することができます.
 
  
(function() {
    var result = eval("var x = 10, y = 20; x + y");
    // strict strict .(resulst 30)
    alert(result);
}());
読み取り専用属性の変更時に例外を投げます.
ECMAScript 5には対象となる特定の属性を読み取り専用にしたり、オブジェクト全体を変更できないようにする能力も導入されています.ただし、厳密でないモードでは、読み取り専用属性を変更しようとしましたが、黙っているだけで失敗しました.いくつかのブラウザとAPIを付き合っているうちに、このような状況に遭遇する可能性が高いです.厳格なモードはこのような状況で明確に異常を投げます.この属性の変更は許可されていません.
 
  
var person = {};
Object.defineProperty(person, "name" {
    writable: false,
    value: "Nicholas"
});
// , , .
person.name = "John";
上記の例では、name属性は読み取り専用として設定されていますが、厳密でないモードでname属性に対する修正を実行するとエラーが発生しません.修正は成功しません.ただし、厳格なモードでは明確に異常を投げます.
NOTE:任意のECMAScript属性特性を使用して指定した場合、厳格なモードを開くことを強く推奨します.
どう使いますか
現代ブラウザでは、厳格なモードを開くことが非常に容易であり、JavaScriptコードの中に以下のコマンドがあるだけでいいです.
「use strict」 
上のコードは変数が与えられていない文字列だけに見えますが、実際にJavaScriptエンジンが厳格なモードに切り替わることを示す役割を果たしています.このコマンドを全体や関数に適用できますが、全体的な環境では厳密なモードを使用しないように注意してください.
 
  
//
"use strict";
function doSomething() {
    //
}
function doSomethingElse() {
    //
}
 
上のコードは大きな問題ではないように見えますが.しかし、ページに導入されたすべてのコードを維持する責任がない場合、このようにstrictモードを使うと、第三者コードが厳格なモードの準備ができていないため、問題が発生します.
したがって、厳密なモードをオンにするコマンドは、関数に作用したほうがいいです.例えば、
 
  
function doSomething() {
    "use strict";
    //
}
function doSomethingElse() {
    //
}
 
厳密なモードを一つ以上の関数で開く場合は、すぐに関数式を実行してください.
 
  
(function() {
    "use strict";
    function doSomething() {
        //
    }
    function doSomethingElse() {
        //
    }
}());
結論
今からJavaScriptの厳格なモードを有効にすることを強く勧めます.コードの中では気づかなかったエラーを発見してくれます.グローバル環境では有効にしないでください.でも、できるだけ多くのIIIFE(すぐに関数式を実行します.)を使って、厳密なモードを複数の関数の範囲に作用させます.最初は、前に会ったことのないエラーメッセージに出会うのが普通です.厳格なモードを有効にすると、サポートされているブラウザでテストが行われ、新たな潜在的な問題が発見されることを確認してください.コードに列を追加するだけで、残りのコードが正常に動作すると仮定しないでください.最後に、より良いコードの作成を厳格なモードで開始してください.
注:ここには厳格なモードに対する各ブラウザのサポート状況のまとめがあります.このページでは、現在のブラウザの厳格なモードサポート度をテストできます.
厳格なモードのメリット:
JavaScriptをより強固にする.      Thisはもうカプセル化されません.normal modeの下で、thisはずっと対象です.2.      Fun.callerとfun.argmentsは削除できる属性ではなく、setまたはretrievedにも利用できません.3.      Agments.callerも削除できない属性です.setやretrievedもできません.
将来のECMAScriptバージョンのために道路を舗装する.      下記の保留文字を追加しました.implements、interface、let、package、prvate、protected、public、staticとyield.2.      メソッド宣言はスクリプトまたはメソッドの先頭に置くべきで、ifまたはforなどの文の間に置くことはできません.