《javascript模式》第2章 基本技巧 中,講了一些在前段編程中的一些規範和建議,同時還有一些平常經常忽視且容易踩中的坑。
以下僅是部分內容的摘要和總結,以做備忘用,如有錯漏,敬請指出。如需瞭解更多,可參閱原著,挺不錯的書。
1 鏈式賦值的陷阱
function func(){ var innerVar = globalVar = 20; }func();console.log(typeof globalVar); //輸出結果為?
上面最後的輸出結果是?相信不少人會毫不猶豫地說undefined,確定?
真相是:number
原因:從右至左操作符的優先順序。首先,優先順序較高的是運算式b=0,此時b未經聲明。運算式的傳回值為0,它被賦給var聲明的局部變數a,如以下代碼所示
var a = (b = 0);
建議:對鏈式賦值的所以變數都進行聲明,再進行賦值
function foo() { var a, b; a = b = 20; //都是局部變數}
2 變數釋放時的副作用
隱含全域變數與明確定義的全域變數有細微的不同,不同之處在於能否使用delete操作符撤銷變數
- 使用var建立的全域變數(這類變數在函數外部建立),不能刪除
- 不使用var建立的隱含全域變數(儘管它是在函數內部建立),可以刪除
這表明隱含全域變數嚴格來講不是真正的變數,而是全域對象的屬性。屬性可以通過delete操作符刪除,但變數不可以
//定義三個全域變數var global_var = 1;global_novar = 2; //反模式(function(){ global_fromfunc = 3; //反模式})();//企圖刪除delete global_var; //falsedelete global_novar; //truedelete global_fromfunc; //true//測試刪除情況typeof global_var; //'number'typeof global_novar; //'undefined'typeof global_fromfunc; //'undefined'
在ES5 strict模式中,為沒有聲明的變數賦值會拋出錯誤
3 for-in的陷阱
var person = { name: 'casper', age: 11};for(var key in person){ console.log(key);}
運行下上述代碼,毫無意外,輸出結果為:
輸出:name輸出:age
將上述代碼稍微修改下又如何呢?
var person = { name: 'casper', age: 11};Object.prototype.getName = function(){}; for(var key in person){ console.log(key);}
輸出結果變成:
輸出:name輸出:age輸出:getName
建議:不要增加內建對象的原型,除非必要,同時需在團隊內進行良好的溝通,確保其他團隊成員不會因此而遇到一些奇怪的錯誤
4 注意eval與new Function之間的差別
- eval()會影響到範圍
- new Function()中的代碼將在局部函數空間中運行,因此代碼中任何採用var定義的變數不會自動成為全域變數
- 無論在哪裡執行Function,它都僅能看到全域範圍
直接看程式碼範例:
console.log(typeof un); //'undefined'console.log(typeof deux); //'undefined'console.log(typeof trois); //'undefined'var jsstring = "var un = 1; console.log(un);";eval(jsstring); //logs "1"jsstring = "var deux = 2; console.log(deux);";new Function(jstring)(); //logs "2"jsstring = "var trois = 3; console.log(trois);";(function(){ eval(jsstring);})(); //logs "3"console.log(un); //'number'console.log(typeof deux); //'number'console.log(typeof trois); //'undefined'
從上面程式碼範例可以很清楚地看出前兩點,關於第三點,請看下面程式碼範例:
(function(){ var local = 1; eval("local = 2; console.log(local);"); //logs 3 console.log(local); //logs 3})();(function(){ var local = 1; new Function("console.log(typeof local);")(); //logs 'undefined'})();