SlideShare 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

Similar to Java script patterns essentials

潜力无限的编程语言Javascript
潜力无限的编程语言Javascript潜力无限的编程语言Javascript
潜力无限的编程语言Javascriptjay li
 
Js的国(转载)
Js的国(转载)Js的国(转载)
Js的国(转载)Leo Hui
 
lambda/closure – JavaScript、Python、Scala 到 Java SE 7
lambda/closure – JavaScript、Python、Scala 到 Java SE 7lambda/closure – JavaScript、Python、Scala 到 Java SE 7
lambda/closure – JavaScript、Python、Scala 到 Java SE 7
Justin Lin
 
Java面试32题
Java面试32题Java面试32题
Java面试32题yiditushe
 
Java面试知识
Java面试知识Java面试知识
Java面试知识yiditushe
 
基于J2 Ee的Web应用
基于J2 Ee的Web应用基于J2 Ee的Web应用
基于J2 Ee的Web应用yiditushe
 
Javascript share
Javascript shareJavascript share
Javascript share
Xu Mac
 
Javascript 入門 - 前端工程開發實務訓練
Javascript 入門 - 前端工程開發實務訓練Javascript 入門 - 前端工程開發實務訓練
Javascript 入門 - 前端工程開發實務訓練Joseph Chiang
 
异步编程与浏览器执行模型
异步编程与浏览器执行模型异步编程与浏览器执行模型
异步编程与浏览器执行模型
keelii
 
JavaScript Advanced Skill
JavaScript Advanced SkillJavaScript Advanced Skill
JavaScript Advanced Skill
firestoke
 
JavaScript closures
JavaScript closuresJavaScript closures
JavaScript closures
Horky Chen
 
JavaScript 教程
JavaScript 教程JavaScript 教程
JavaScript 教程
Bobby Zhou
 

Similar to Java script patterns essentials (12)

潜力无限的编程语言Javascript
潜力无限的编程语言Javascript潜力无限的编程语言Javascript
潜力无限的编程语言Javascript
 
Js的国(转载)
Js的国(转载)Js的国(转载)
Js的国(转载)
 
lambda/closure – JavaScript、Python、Scala 到 Java SE 7
lambda/closure – JavaScript、Python、Scala 到 Java SE 7lambda/closure – JavaScript、Python、Scala 到 Java SE 7
lambda/closure – JavaScript、Python、Scala 到 Java SE 7
 
Java面试32题
Java面试32题Java面试32题
Java面试32题
 
Java面试知识
Java面试知识Java面试知识
Java面试知识
 
基于J2 Ee的Web应用
基于J2 Ee的Web应用基于J2 Ee的Web应用
基于J2 Ee的Web应用
 
Javascript share
Javascript shareJavascript share
Javascript share
 
Javascript 入門 - 前端工程開發實務訓練
Javascript 入門 - 前端工程開發實務訓練Javascript 入門 - 前端工程開發實務訓練
Javascript 入門 - 前端工程開發實務訓練
 
异步编程与浏览器执行模型
异步编程与浏览器执行模型异步编程与浏览器执行模型
异步编程与浏览器执行模型
 
JavaScript Advanced Skill
JavaScript Advanced SkillJavaScript Advanced Skill
JavaScript Advanced Skill
 
JavaScript closures
JavaScript closuresJavaScript closures
JavaScript closures
 
JavaScript 教程
JavaScript 教程JavaScript 教程
JavaScript 教程
 

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