JavaScript-Patterns-2012-閱讀[1-2]

頁碼 p.16 ~ p.22

for迴圈(重複陣列)

可遍歷整個陣列或類似陣列的物件

1
2
3
4
5
6
7
8
9
// 這個寫法,每次都要存取陣列的長度,這會拖慢你的程式
for(var i = 0; i < myArray.length; i++) {
// do something ...
}

// 這個寫法,只需計算一次length,用於整個迴圈中 👍
for(var i = 0, max = myArray.length; i < max ; i++) {
// do something ...
}

迴圈模式的變形。優化效能

  • 可少用一個變數(這邊指 max)👍
  • 遞減至0,通常比較快 👍
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // 第一種
    var i, myArray = [];

    for(i = myArray.length; i--;) {
    // do something ...
    }

    // 第二種
    var myArray = [],
    i = myArray.length;

    while(i--) {
    // do something ...
    }

for-in迴圈(重複物件)

用來歷整整個非陣列物件,又稱「列舉 enumeration」

  • 使用 hasOwnProperty() 過濾掉來自原型鏈的屬性

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    // 1. 建立一個物件
    var family = {
    sisters: 2,
    brothers: 1,
    father: 1
    }

    // 2. 將clone方法,加到所有物件中。用擴充Object原型
    if(typeof Object.prototype.clone === "undefined") {
    Object.prototype.clone = function() {}
    }

    // 3. 使用 for-in,並搭配 hasOwnProperty(),來印出屬性
    for(var i in family) {
    if (family.hasOwnProperty(i)) { // 過濾掉原型鏈的屬性
    console.log(i, ":" , family[i])
    }
    }
    /*
    會印出這些:
    sisters : 2
    brothers : 1
    father : 1
    */

    // 4. 使用 for-in,直接印出屬性
    for(var i in family) {
    console.log(i, ":" , family[i])
    }
    /*
    會印出這些:
    sisters : 2
    brothers : 1
    father : 1
    clone : ƒ () {} // 多了這個
    */
  • 也可使用,Object.prototype呼叫 hasOwnProperty()

    • 避免命名衝突
    • 若嫌這句話太長,可以用一個區域變數快取它
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      // 使用 Object.prototype 呼叫
      for(var i in family) {
      if (Object.prototype.hasOwnProperty.call(family, i)) {
      console.log(i, ":" , family[i])
      }
      }

      // 使用變數快取
      var i,
      hasOwn = Object.prototype.hasOwnProperty;
      for(var i in family) {
      if (hasOwn.call(family, i)) {
      console.log(i, ":" , family[i])
      }
      }

      // 上述兩個結果都跟上面,用 hasOwnProperty() 判斷的一樣

不要擴充內建型別的原型


switch

下面模式提升可讀性和穩健性

1
2
3
4
5
6
7
8
9
10
11
12
13
var inspect_me = 0,
result = '';

switch(inspect_me) {
case 0:
result = 'zero';
break;
case 1:
result = 'one';
break;
default:
result = 'unknow';
}

  • 將每個 case 與 switch 並排

  • 每個 case 內的程式碼縮排

  • 用 break; 結束每個 case

  • 用 default; 結束 switch,即使沒有任何一個 case 符合

    同系列下篇:JavaScript-Patterns-2012-介紹[1-3]