【訳】Javascriptの厳しいパターンを使う時です.

4719 ワード

Nichollas C.Zakas 2012-3-13原文はここを強打してください.
ECMAScript 5は厳格なモードをJavascriptに導入しました.目的は開発者が「より良い」Javascriptバージョンを選択できるようにすることです.このバージョンは普遍的で悪名高いエラーを異なる方法で処理することができます.最初は一つのブラウザしかないので、このモードに対しては疑問を持っていました.厳しいモードをサポートしていました.現在では、すべての主流ブラウザの最新バージョンは、IE 10とOpera 12を含む.厳格なモードを使うタイミングが熟成しました.
何を持ってきましたか?
厳格なモードはJavascriptの運行方式に多くの違いをもたらしました.それらを二つの種類に分けます.明らかなのと微妙なのです.それらの微妙な変化は微妙な問題を解決するためであり、ここでそれをくどくど説明するつもりはない.これらの詳細に興味があるなら、Dmitry Soshnikovの素晴らしい文章を参照してください.明らかな変化を紹介することに興味があります.厳格なパターンを使う前に知っておくべきです.一番いいところを持ってくるかもしれません.
特殊な特性を紹介する前に、厳格なモードの目標の一つは、より速くデバッグすることを許可することです.開発者のデバッグを支援する最善の方法は、問題が発生した時に、相応のエラーを出すことである.厳格なモードのコードがより多くのエラーメッセージを投げたのはいいことです.開発者がすぐに問題を解決しなければならないことに気づいてくれるからです.
with文を削除(Eliminates with)
まず、厳密モードではwith文が削除されます.with文が厳格なモードに現れたとき、それは不法なJavascript文と見なされ、文法的なエラーを投げかけることができます.ですから、厳格なモードを使う第一歩はwithを使っていないことを確認することです.
//              
with (location) {
    alert(href);
}
予期しないグローバル変数(Prventts accidental globals)を防止します.
第二のポイントは、変数が賦課される前に宣言しなければなりません.非厳密モードでは、宣言されていない変数に値を割り当てると自動的にグローバル変数が生成されます.これはJavascriptの中で最も普遍的な誤りの一つです.厳格なモードでは、このようにするとエラーが発生します.
//            
(function() {
    someUndeclaredVar = "foo";
}());
this値の強制変換をキャンセルします(Eliminates this coercion)
もう一つの重要な変化は、this値がnullまたはundefinedの場合、これをグローバルオブジェクトに強制的に変換しないことである.つまり、thisは元の値を保持しており、強制変換に依存するコードにエラーが発生する可能性があります.たとえば:
window.color = "red";
function sayColor() {
    //      ,this    window
    alert(this.color);
}

//       ,           
sayColor();
sayColor.call(null);
基本的には、this値は、undefined値を保持します.これは、構造関数を呼び出した時にnewキーワードを落としたら、エラーが発生することを意味します.
function Person(name) {
    this.name = name;
}

//          
var me = Person("Nicholas");
このコードの中で、Personコンストラクタを呼び出す時はnewキーワードが不足しています.この時、this値はundefinedです.undefinedに属性を追加できないので、このコードはエラーを残しました.非厳密モードでは、thisはグローバルオブジェクトに強制的に変換されますので、name属性はグローバル変数として正しく割り当てられます.
重複を拒否(No duplicates)
大量の符号化を行うと、繰り返し属性をオブジェクトに定義したり、関数に繰り返しパラメータ名を定義したりしやすくなります.厳格なモードでは、この2つの場合にエラーが発生します.
//         -     
function doSomething(value1, value2, value1) {
    //code
}

//         -     
var object = {
    foo: "bar",
    foo: "baz"
};
どちらも文法エラーです.コード実行前にエラーを投げます.
より安全なeval()(Safer eval()
eval()は除去されていませんが、厳密なモードでいくつかの変化があります.最大の変更は、eval()文で宣言された変数および関数が含まれているドメインでは作成されません.たとえば:
(function() {

    eval("var x = 10;");

    //       ,x 10
    //      ,x    ,      
    alert(x);

}());
eval()によって作成された変数や関数はそのままeval()にあります.しかし、値の伝達はeval()から値を返すことによって達成され得る.
(function() {

    var result = eval("var x = 10, y = 20; x + y");

    //                  (  30)
    alert(result);

}());
誘発されたエラーを変えてはいけません.
ECMAScript 5は、属性の特徴を修正する能力を同時に導入し、例えば、読み取り専用またはオブジェクト全体を凍結する構造(freezing an entire object’s structure)を設定する.非厳密モードでは、可変ではない属性を変更しようとしたときに、音もなく失敗します.いくつかの原生APIを使う時、すでにこのような問題に遭遇したかもしれません.厳密なモードは、オブジェクトまたはオブジェクトの属性を変更する際に、許可されない方法で変更しようとしたときにエラーが発生することを保証します.
var person = {};
Object.defineProperty(person, "name" {
    writable: false,
    value: "Nicholas"
});

//               ,         
person.name = "John";
この例では、name属性は読み取り専用に設定されている.非厳格モードでは、nameに対する赋価は音もなく失败します.厳しいモードでは、エラーは投げ出されます.
注:ECMAScript属性能力(the ECMAScript atribute capability)を使っているなら、厳しいモードを開くことを強く勧めます.オブジェクトの可変性を変えると、それらは非厳格モードで静かに過されます.
どうやって使うべきですか?
現代のブラウザでは、厳格なモードが有効になりやすいです.次のステートメントを追加するだけでいいです.
"use strict";
これは変数に割り当てられていない文字列にしか見えませんが、Javascriptエンジンが厳格なモードに切り替わることを確実に示しています.大域または関数で使用できます.そうは言っても、あなたは永遠に全体の中でそれを使うべきではありません.全体的にこの指示を使用すると、同じファイルのすべてのコードが厳格なモードで実行されることを意味します.
//     
"use strict";

function doSomething() {
    //           
}

function doSomethingElse() {
    //    
}
これは大きな問題ではないように見えますが、私たちのこの違う脚本が一緒に集まっている世界では大変なことになります.このコマンドがシナリオ全体に含まれている限り、他の直列スクリプトも厳格なモードで実行されます.
したがって、厳密なモードは関数内だけで使用することが望ましい.
function doSomething() {
    "use strict";
    //        
}

function doSomethingElse() {
    //         
}
厳密なモードを複数の関数に適用したい場合は、以下のパターンが使えます.
(function() {

    "use strict";

    function doSomething() {
        // this runs in strict mode
    }

    function doSomethingElse() {
        // so does this
    }
}());
結論
誰もが厳格なモードを使い始めることを強く勧めます.今はもう十分多くのブラウザがこのモードをサポートしています.隠しコードのエラーからあなたを救い出します.有効命令が大域的に含まれていないことを確認してください.ただし、頻繁にIIIFEsを使って任意のコードに厳しいモードを適用できます.最初に、あなたは今まで会ったことのないミスに出会うでしょう.これは正常です.厳格なモードに切り替えた後、十分なテストが必要です.必ず「use strict」だけをあなたのコードに入れてはいけません.間違いがないと仮定してください.少なくとも、この非常に有用な言語特性を使用して、より良いコードを書き始めるべきです.