9. 寫 JavaScript 的好習慣 (Good Practice)
宣告一個變數時記得前面一定要加 var 。雖然不加 var 也是
JavaScript 可接受的寫法 ( 會變成 global variable) ,但是這樣
容易造成混洧和發生錯誤。
儘量避免明示宣告一個 primitive wrapped object(String,
Boolean, Number ,例 : var str = new String(‘test…’);) 。因為
這會讓開發者搞不清楚他們是在處理 reference value or
primitive value ,容易造成混洧。
10. 寫 JavaScript 的好習慣 (Good Practice)
在一個遞迴 (recursive) 或匿名 (anonymous) 函式裡,最好使
用 arguments.callee 代替指定 function name 。這樣一來,日
後即使換了 function name(reference) ,也不用跟著調整
function code 裡面寫到的名稱。
// a recursive function
function grabData() {
if( storage.length > 0 ) { // storage is a array
var obj = storage.shift();
// your handle code here
var method = arguments.callee;
window.setTimeout(function() {
method(); // execute grabData method actually
}, 300);
}
}
16. 寫 JavaScript 的好習慣 (Good Practice)
當一段程式邏輯需要耗費大量時間運算時,可以試著將可分
割的程式區塊切成數小段,用 setTimeout 指定一小段時間間
隔後再執行。這樣可以讓頁面有更多喘息的時間來回應使用
者的操作行為,而有更好的使用者互動經驗。
// 原本的寫法
function insertItem() {
var panel = document.getElementById('my_panel');
for( var i=0; i<100; i++ ) {
var item = document.createElement('div');
item.innerHTML = 'Item-'+i;
item.onmouseover = function() {
this.style['background'] = 'gold';
};
item.onmouseout = function() {
this.style['background'] = 'transparent';
};
// ... other handle codes
panel.appendChild(item);
}
}
// 新的寫法
var count = 0;
function insertItem(index) {
if( index >= 100 ) return;
var panel = document.getElementById('my_panel');
var item = document.createElement('div');
item.innerHTML = 'Item-'+index;
item.onmouseover = function() {
this.style['background'] = 'gold';
};
item.onmouseout = function() {
this.style['background'] = 'transparent';
};
// ... other handle codes
panel.appendChild(item);
// delay a while to let browser take a break
var method = arguments.callee;
window.setTimeout(function() {
method(count++);
}, 50);
}
17. 寫 JavaScript 的好習慣 (Good Practice)
將 Event Handler 裡面的商業邏輯獨立出來。 Event Handler
應該只處理與 Event 有關資料,例如抓取 keyPress event 的
keyCode 或 event target 。若要利用這些值做一些處理,則改
在別的 function 裡做。不要 pass event object 到 Event
Handler 以外的地方。
// 原本的 code
function handleKeypress(event) {
if( event.keyCode == 13 ) {
var target = EventUtil.getTarget(event);
var value = 5 * parseInt(target.value);
if( value > 10 ) {
var elm = document.
getElementById('error-msg');
elm.style.display = 'block';
}
}
}
// 改寫後的 code ,將商業邏輯獨立出來
function validateValue(value) {
value = 5 * parseInt(value);
if( value > 10 ) {
var elm = document
.getElementById('error-msg');
elm.style.display = 'block';
}
}
function handleKeypress(event) {
if( event.keyCode == 13 ) {
var target = EventUtil.getTarget(event);
validateValue(target.value);
}
}
18. 寫 JavaScript 的好習慣 (Good Practice)
儘量減少 access global variable 的次數可以增進效能,因為
減少了 traverse time 。如果一個 function 裡有數個地方會
access 同一個 global variable( 如 : document) ,可以先用一
個 local variable 去指向 global variable ,後續的 code 再
access local variable ,這樣可加快速度。
// 原本的 code
function updateUI() {
var imgs = document
.getElementsByTagName('img');
for( var i=0, len=imgs.length; i<len, i++ ) {
imgs[i].title = document.title + 'image' + i;
}
var msg = document.getElementById('msg');
msg.innerHTML = 'Update complete';
}
// 改寫後的 code ,先宣告一個 local variable 去記
// document
function updateUI() {
var doc = document;
var imgs = doc.getElementsByTagName('img');
for( var i=0, len=imgs.length; i<len, i++ ) {
imgs[i].title = doc.title + 'image' + i;
}
var msg = doc.getElementById('msg');
msg.innerHTML = 'Update complete';
}
19. 寫 JavaScript 的好習慣 (Good Practice)
如果要建立一個 Storage 來存放資料時,用 Array 會比 Object
快。在 Access 資料的速度上,前者的複雜度為 O(1) ,後者
為 O(n) 。
若一段 code 有很多 if-else 時,改採用 switch 寫法執行速度會
比較快一些。另外可以將比較容易 match 到的 case 條件排在
比較上面,比較少 match 到的 case 排在下面,也會讓效能上
有些許提昇。
20. 寫 JavaScript 的好習慣 (Good Practice)
儘量減少對 DOM 的操作會使效能有非常顯著的提升, DOM
的運算是 Browser 裡最耗運算資源的。當要對一個 HTML
element 連續插入很多或複雜的 child element 時,可以用
DocumentFragment 先將整個 DOM 結構建立好,再一次加進
element ,速度會快很多 !
// 原本的寫法
function insertItem() {
var panel = document.getElementById('my_panel');
for( var i=0; i<100; i++ ) {
var item = document.createElement('div');
item.innerHTML = 'Item-'+i;
item.onmouseover = function() {
this.style['background'] = 'gold';
};
item.onmouseout = function() {
this.style['background'] = 'transparent';
};
// ... other handle codes
panel.appendChild(item);
}
}
// 改寫後的 code ,將 item 寫進 DocumentFragment
function insertItem() {
var panel = document.getElementById('my_panel');
var fragment = document
.createDocumentFragment();
for( var i=0; i<100; i++ ) {
var item = document.createElement('div');
item.innerHTML = 'Item-'+i;
item.onmouseover = function() {
this.style['background'] = 'gold';
};
item.onmouseout = function() {
this.style['background'] = 'transparent';
};
fragment.appendChild(item);
// ... other handle codes
}
panel.appendChild(fragment);
}
21. Naming Rule
Variable 請用小寫名詞,如 : person, card 。
Function 請用小寫動詞開頭,如 : getName(), pushEvent() 。
假如 Function 會回傳一個 Boolean 值,請用 is 開頭,如 :
isEnabled(), isVisible() 。
Constant 請用大寫及底線,如 : STATE, EVENT_TYPE 。
如果是 private 使用,可以在 Variable 及 Function 字首加上底
線。如 : _target, _getElement() 。
HTML Element 的 class name 、寫入 Cookie 或發送 HTTP
Request 的參數名稱請用底線 '_' 區隔單字。如 :
'window_panel', 'personal_setting', 'widget_position' 。
22. Convention Rule
在 JavaScript 裡,字串用單引號標示,在 HTML 裡用雙引號
標示。當規則定下來之後,如果有一天需要把 HTML element
改由 JavaScript 動態產生,就可以直接覆製 HTML code 到
JavaScript 字串變數裡,不需再擔心單雙引號相衝的問題。
縮排 Tab 改用空白取代。這是為了防止當很多人一起改 code
時,程式碼會因為每個人的編輯器不同, Tab 所表示的空白
字元數不同,而導致程式碼縮排不一致變的亂七八糟。
// in JavaScript
var str = 'Hello World';
// in HTML
<div class=“err-msg“></div>
// 假如必須要在 JavaScript 裡直接寫 HTML code
var html = '<div class=“err-msg“></div>';