<<br>>ノートを読む--第2章基本テクニック(二)

11733 ワード

for-inループについて
データをループする場合は、for-inループの使用は強く推奨されない.Arrayオブジェクトが拡張された後、for-inでデータをループすると、論理的なエラーが発生するため、例を示します.
var arr = ['a', 'b', 'c'];

//     

for(var i=0, len=arr.length; i<len; i++) {

    console.info(typeof i); // number

    console.info(i);

}

// for-in  

for(var i in arr) {

    console.info(typeof i); // string

    console.info(i);

}

console.log(arr.length); // 3

このとき、for-inが配列を巡る場合、iのタイプはstringであり、配列の下付きではなく、配列オブジェクトのkeyとして現れる(Javascriptでは配列もオブジェクトである).
ループ前に次のコードを付けると、for-inループで論理的なエラーが発生します.
if(typeof Array.prototype.len === 'undefined') {

    Array.prototype.len = function() {

        return this.length;

    };

}

すなわち配列にプロトタイプメソッドlen()を追加する
console.log(arr.length);//出力は3
しかし、for-inループは同時にlenを出力し、これはfor-inが確かにArrayをObjectとして遍歴していることを示しており、lenがオブジェクトとしての属性も自然に遍歴する.
要するに、プロトタイプに方法をむやみに追加することはできず、他の人ができないことは保証できないので、for-inループ配列を使用しないほうがよい.
 
for-inを使用してオブジェクトを巡回する場合、hasOwnProperty()とともに一般的に使用され、hasOwnProperty()はプロトタイプ属性またはプロトタイプメソッドをフィルタするために使用されます.例:
//     person  ,            

var person = {

    name: '  ',

    age: 28,

    say: function() {

        // ...

    }

}

//  Object       sleep()

if(typeof Object.prototype.sleep === 'undefined') {

    Object.prototype.sleep = function() {

        // ...

    }

}

//   hasOwnProperty() for-in  

for(var i in person) {

    if(person.hasOwnProperty(i)) {

        console.info(i);

    }

}

/*

       :

name

age

say

 */

//    hasOwnProperty() for-in  

for(var i in person) {

    console.info(i);

}

/*

       :

name

age

say

sleep

 */

なお、hasOwnProperty()を使用しないことは間違いないが、ループ結果に混乱をもたらす可能性があり、自分のコードに十分な自信があれば、hawOwnProperty()を使用することなく、ループ速度を少し向上させることができる.
 
 
内蔵のプロトタイプを増やさない
内蔵プロトタイプに方法や属性を追加することは強力な機能であるが、その強さこそメンテナンスに大きなコストをもたらすことが多い.また、上記のように内蔵プロトタイプを拡張すると、hasOwnProperty()を使用しないサイクルで若干の混乱を招く.
プロトタイプを拡張する必要がある場合は、カスタム属性やメソッドがすでに存在するかどうかを確認し、存在しない場合は拡張し、ドキュメントで記録してチームコミュニケーションを行う必要があります.次のモードでは、プロトタイプを拡張できます.
if(typeof Object.prototype.myMethod === 'undefined') {

    Object.prototype.myMethod = function() {

        // ...

    }

}

 
 
 
隠し型変換の使用を避ける
Javascriptにはfasle==0,"==0のような隠れたタイプの変換があり、このような比較文はtrueに戻り、ある程度混同され、タイプが不明になる.
したがって、比較比較文では==と!==を使用することをお勧めします.数値とタイプの比較
 
 
eval()の使用を避ける
最初の言葉「eval()は悪魔」
通常、事前に作成されたコードはeval()を使用する必要はありません.コードが実行中に動的に生成された場合、eval()を使用してJavascriptコードに変換する必要がある場合がありますが、eval()の代わりにより良い方法があります.このような場合、ajaxの戻り値を処理する場合、例えば、次のような場合が多いです.
// ajax         "name",       obj      ,   name     , '  '     

var property = "name";

var obj = {

    age: 22

};

//    ,     

// eval('obj.' + property + '= "z3"');

//   

obj[property] = '  ';

for(var i in obj) {

    console.info(i);

}

 
eval()を使用することもいくつかの危険性を含み、改ざんされたコードを実行する可能性がある.
また、setInterval()とsetTimeout()の呼び出しはeval()と同様の問題があります.
//    

setTimeout(“myFunc()”, 1000);

setTimeout(“myFunc(2, 5, 7)”, 1000);

//   

setTimeout(myFunc, 1000);

setTimeout(function(){

    myFunc(2, 5, 7);

}, 1000);

eval()を必ず使用するならば、eval()の代わりにnew Function()を用いることができるかどうかを考えることができる.
new Function()コードを使用するとローカル関数空間で実行されるため、var定義を使用する変数は自動的にグローバル変数にはなりません.たとえば、次のようになります.
new Function("var p = 3; console.info(p);")(); // 3

console.info(p); // ReferenceError: p is not defined

eval("var p1 = 4; console.info(p1);"); // 4

console.info(p1); // 4

グローバル変数の自動化を防止するもう1つの方法は、eval()を即時実行関数に閉じることです.たとえば、次のようにします.
(function(){

    eval('var num = 11; console.info(num);'); // 11

})();

console.info(num); // ReferenceError: p is not defined

 
new Function()とeval()のもう一つの違いは、eval()が作用ドメインチェーンに影響するが、new Function()が局所変数に与える影響は比較的小さいことである.
eval()はその外部作用ドメインの変数にアクセスして修正することができ、new Function()はできない.例:
(function(){

    var num = 13;

    eval('var num = 20; console.info(num);'); // 20

    console.info(num); //20,    num  

})();

(function(){

    var num = 12;

    new Function('var num = 17; console.info(num);')(); // 17

    console.info(num); // 12

})();

 
 
 
parseInt()の数値規則の使用
この約束は主にECMAScriptの新旧バージョンが一致しない問題を解決するために、
ECMAScriptの初期バージョンでは、0の先頭の文字列が8進数として扱われ、ECMAScript 5で変更されたので、parseInt()メソッドを使用する場合は、2番目のパラメータ(進数パラメータ)を無視しないほうがいいです.
たとえば、日付文字列を処理する場合:
var month = '07',

    date = '02';

month = parseInt(month, 10);

date = parseInt(date, 10);

また、「09」などの純粋な数値文字列を変換する場合は、Number('09')を使用するとより効率的になります.
「02 hello」などの非純数値文字列の場合、parseInt('02 hello')を使用するだけで、Number('02 hello')はNaNを返します.
 
 
コーディング規則
本で述べた符号化規則は,コードの可読性を向上させ,コードのメンテナンスコストを低減するために,
インデント、空間、括弧、命名規則、スペースの使用などが含まれる.
ここで、カッコの位置に注意してください.セミコロンの挿入メカニズムにより、いくつかのコードの実行結果が予想外になります.たとえば、次のようになります.
//          

function func() {

    return

    {

        name: '  '

    };

}

console.info(func()); // undefined;

//        

function func1() {

    return undefined;

    {

        name: '  '

    };

}

//   ,                  :

function func3() {

    return {

        name: '  '

    };

}