1.js執行順序
Code:
myname = "global"; // 全域變數
function func() {
alert(myname); // "undefined"
var myname = "local"; alert(myname);
alert(myname); // "local"
}
func();
Say:
js編譯器會先執行聲明然後再執行賦值的操作。簡單來說先執行聲明(var聲明的變數或者是function聲明的函數)把記憶體都分配好,然後再往記憶體裡賦值。
2.迴圈的最佳化
Code:
//迴圈1
for
(var i = 0; i < myarray.length; i++) {
// 使用myarray[i]做點什麼
}
//迴圈2
var max;
for
(var i = 0, max = myarray.length; i < max; i++) {
// 使用myarray[i]做點什麼
}
Say:
迴圈2比迴圈1執行快,因為不用每次擷取數組的長度。這個本人經常會用1的形式,所以以後一定要改。
3.hasOwnProperty來取消超類的原型方法
Code:
//代碼1 for (var i in man) { if (man.hasOwnProperty(i)) { // 過濾 console.log(i, ":", man[i]); } }
//代碼2
var i, hasOwn = Object.prototype.hasOwnProperty; for (i in man) { if (hasOwn.call(man, i)) { // 過濾 console.log(i, ":", man[i]); } }
Say:
hasOwnProperty主要是查詢方法是否是對象自己的方法。從而達到過濾超類方法的方法。這個也可以作為提升for迴圈執行效率的作用。
4.parseInt數值轉換
Code:
//代碼1
var month = "06", year = "09"
day="08"; month = parseInt(month, 10); year = parseInt(year, 10);
day = parseInt(day);//結果是0,因為作為8進位來轉了,所以出錯
//代碼2
+"08" // 結果是 8 Number("08") // 8
Say:
parseInt其實有2個參數,後面的參數代表的是進位,所以09可以轉換成9.代碼2提供的是其他轉換方式,值得一提的是,代碼2的轉換方式要比代碼1來得快。
5.不要使用var f=function g(){函數體...}
Code:
//代碼1
var f = function g(){}; typeof g; // "function"
//代碼2
typeof g; // "function" var f = function g(){};
//代碼3
var f = function g(){}; f === g; // false f.expando = 'foo'; g.expando; // undefined
//代碼4
var f = function g() { return 1; }; if (false) { f = function g(){ return 2; }; } g(); // 2
Say:
代碼1和2表示聲明了函數g以後,無論在何處調用,都會存在該對象。說明這樣聲明函數其實和賦值不複製給f無關,可以當做一個函式宣告來處理
代碼3表示f和g其實並不是一個對象,這個其實很迷惑,可以認定為是js的bug
代碼4也說明了函式宣告並不涉及到實際代碼,雖然你放在了判斷語句中,但是聲明還是會存在的,不過我們實際寫代碼過程中應該不要用邏輯來選擇如何建立函數,而是應該將邏輯放在函數內部比較好,否則容易造成迷惑,雖然這樣可能會在效率上不如前者。
綜上所述,千萬別使用var f=function g(){};,當做不知道吧。
摘自 JerryVon的專欄