狠狠撸

狠狠撸Share a Scribd company logo
JavaScript Patterns 
CHAPTER 2 
Essentials 
jason wang
撰寫可維護的程式碼 
? 1. 可讀性 
? 2. 一致性 
? 3. 可預料性 
? 4. 看起來像同一人寫的 
? 5. 文件化
全域變數問題 
? 1. 你可以不用宣告直接使用變數 
? 2. JavaScript有隱含全域變數的觀念 
意思就是未宣告使用的變數都會自動成為 
全域變數!!?
隱含的全域變數 
function sum(x, y) { 
result = x + y; //隱含全域變數 
return result; 
} 
因此只要呼叫sum 函數一次 
便會在全域命名空間中多一個變數result 
超方便的(大誤
另一種隱含全域變數陷阱 
function foo() { 
var a = b = 0; // a 為區域變數b卻是全域變數 
… 
} 
因為由右至左的運算 
首先計算b = 0但b未宣告, 運算式回傳0 
並指派新區域變數var a 
整段運算式如同:var a = (b = 0);
如何避免隱含全域變數陷阱 
? 1. 永遠使用var宣告變數 
? 2. 宣告中注意連鎖賦值問題 
function foo() { 
var a ,b; 
a = b = 0; 
}
單一var 模式 
? 1. 找變數時只需要一個地方 
? 2. 避免邏輯錯誤 
? 3. 減少全域變數的產生 
? 4. 減少程式碼 
function func() { 
var a = 1, 
b = 2, 
sum = a + b, 
myobject = {} 
}
分散的var 造成的問題 
myname = 'global'; 
function func() { 
alert(myname); // 'undefined' 
var myname = 'loacl'; 
alert(myname); // 'loacl' 
} 
很遺憾的alert(myname); 會印出undefined (淚目 
因為myname 在func 中被視為區域變數 
雖然宣告後面才發生...(變數由內往外搜尋) 
所以為避免混淆最好在開頭時就宣告要使用的變數
for 迴圈 
減少對HTMLCollection 重覆存取的動作 
例如 
? document.getElementsByName() 
? document.getElementsByClassName() 
? document.getElementsByTagName()
for 的優化 
1.事先取得某物件的集合長度 
var i, 
max = wArray.length; 
for (i = 0; i < max; i++) { 
// code; 
} 
2.將變數宣告放至for內 
for (var i = 0, max = wArray.length; i < max; i++){ 
// code; 
}
for 的極致變化 
? 1.少用一個變數 
? 2.遞減至0 :因為和0 比較,會比和陣列長 
度或任何東西比較更有效率 
模式一 
var i, 
myarray = []; 
for (i = myarray.length; i--;) { 
// 操作myarray[i]; 
} 
模式二 
var myarray = [], 
i = myarray.length; 
while (i--) { 
//操作myarray[i]; 
}
避免隱含的型別轉換 
1. JavaScript 在比較變數時會隱含的做型別轉換 
列如: false == 0 或''== 0 會回傳true 
2.使用=== 和!== 運算子做比較,可以同時比較運算 
結果的型別跟值 
var zero = 0 
if (zero === false) { 
// 不會執行因為zero 是0 不是false 
}
避免使用eval() 
? 1.因為eval 刮號內的字串需要被解析才能執行, 
嚴重拖慢效能 
? 2.使用eval 有安全性問題,很容易被駭 
? 3.改善setInterval() , setTimeout() 
錯誤寫法 
setTimeout('myFunc(1,2,3)', 1000); 
修正後 
setTimeout(function(){ 
myFunc(1,2,3); 
}, 1000)
改用new Function() 取代eval() 
console.log(typeof un); // undefinded 
console.log(typeof deux); // undefinded 
// eval() 與new Function() 的宣告方式 
var jsstring = 'var un = 1; console.log(un);'; 
eval( jsstring); // log 1 
jsstring = 'var deux = 2; console.log(deux);'; 
new Function(jsstring)(); // log 2 
// 由下列log得知eval() 會干擾到區域的變數 
// 而new Function() 則是內部封閉著變數 
console.log(typeof un); // number 
console.log(typeof deux); // undefinded

More Related Content

Java script patterns essentials

  • 1. JavaScript Patterns CHAPTER 2 Essentials jason wang
  • 2. 撰寫可維護的程式碼 ? 1. 可讀性 ? 2. 一致性 ? 3. 可預料性 ? 4. 看起來像同一人寫的 ? 5. 文件化
  • 3. 全域變數問題 ? 1. 你可以不用宣告直接使用變數 ? 2. JavaScript有隱含全域變數的觀念 意思就是未宣告使用的變數都會自動成為 全域變數!!?
  • 4. 隱含的全域變數 function sum(x, y) { result = x + y; //隱含全域變數 return result; } 因此只要呼叫sum 函數一次 便會在全域命名空間中多一個變數result 超方便的(大誤
  • 5. 另一種隱含全域變數陷阱 function foo() { var a = b = 0; // a 為區域變數b卻是全域變數 … } 因為由右至左的運算 首先計算b = 0但b未宣告, 運算式回傳0 並指派新區域變數var a 整段運算式如同:var a = (b = 0);
  • 6. 如何避免隱含全域變數陷阱 ? 1. 永遠使用var宣告變數 ? 2. 宣告中注意連鎖賦值問題 function foo() { var a ,b; a = b = 0; }
  • 7. 單一var 模式 ? 1. 找變數時只需要一個地方 ? 2. 避免邏輯錯誤 ? 3. 減少全域變數的產生 ? 4. 減少程式碼 function func() { var a = 1, b = 2, sum = a + b, myobject = {} }
  • 8. 分散的var 造成的問題 myname = 'global'; function func() { alert(myname); // 'undefined' var myname = 'loacl'; alert(myname); // 'loacl' } 很遺憾的alert(myname); 會印出undefined (淚目 因為myname 在func 中被視為區域變數 雖然宣告後面才發生...(變數由內往外搜尋) 所以為避免混淆最好在開頭時就宣告要使用的變數
  • 9. for 迴圈 減少對HTMLCollection 重覆存取的動作 例如 ? document.getElementsByName() ? document.getElementsByClassName() ? document.getElementsByTagName()
  • 10. for 的優化 1.事先取得某物件的集合長度 var i, max = wArray.length; for (i = 0; i < max; i++) { // code; } 2.將變數宣告放至for內 for (var i = 0, max = wArray.length; i < max; i++){ // code; }
  • 11. for 的極致變化 ? 1.少用一個變數 ? 2.遞減至0 :因為和0 比較,會比和陣列長 度或任何東西比較更有效率 模式一 var i, myarray = []; for (i = myarray.length; i--;) { // 操作myarray[i]; } 模式二 var myarray = [], i = myarray.length; while (i--) { //操作myarray[i]; }
  • 12. 避免隱含的型別轉換 1. JavaScript 在比較變數時會隱含的做型別轉換 列如: false == 0 或''== 0 會回傳true 2.使用=== 和!== 運算子做比較,可以同時比較運算 結果的型別跟值 var zero = 0 if (zero === false) { // 不會執行因為zero 是0 不是false }
  • 13. 避免使用eval() ? 1.因為eval 刮號內的字串需要被解析才能執行, 嚴重拖慢效能 ? 2.使用eval 有安全性問題,很容易被駭 ? 3.改善setInterval() , setTimeout() 錯誤寫法 setTimeout('myFunc(1,2,3)', 1000); 修正後 setTimeout(function(){ myFunc(1,2,3); }, 1000)
  • 14. 改用new Function() 取代eval() console.log(typeof un); // undefinded console.log(typeof deux); // undefinded // eval() 與new Function() 的宣告方式 var jsstring = 'var un = 1; console.log(un);'; eval( jsstring); // log 1 jsstring = 'var deux = 2; console.log(deux);'; new Function(jsstring)(); // log 2 // 由下列log得知eval() 會干擾到區域的變數 // 而new Function() 則是內部封閉著變數 console.log(typeof un); // number console.log(typeof deux); // undefinded