JavaScript 最佳實踐
請避免全局變量、new
、===
、eval()
始終聲明局部變量
所有在函數中使用的變量應該被聲明為局部變量。
局部變量必須通過 var 關鍵詞來聲明,否則它們將變成全局變量。
嚴格模式不允許未聲明的變量。
在頂部聲明
一項好的編碼習慣是把所有聲明放在每段腳本或函數的頂部。
這么做的好處是:
- 獲得更整潔的代碼
- 提供了查找局部變量的好位置
- 更容易避免不需要的全局變量
- 減少不需要的重新聲明的可能性
// 在頂部聲明 var firstName, lastName, price, discount, fullPrice; // 稍后使用 firstName = "Bill"; lastName = "Gates"; price = 19.90; discount = 0.10; fullPrice = price * 100 / discount;
也可以用于循環變量:
// 在頂部聲明 var i; // 稍后使用 for (i = 0; i < 5; i++) {
默認地,JavaScript 會將所有聲明移至頂部(JavaScript hoisting)。
初始化變量
在您聲明變量時對其進行初始化是個好習慣。
這么做的好處是:
- 更整潔的代碼
- 在單獨的位置來初始化變量
- 避免未定義值
// 在開頭進行聲明和初始化 var firstName = "", lastName = "", price = 0, discount = 0, fullPrice = 0, myArray = [], myObject = {};
變量初始化使我們能夠了解預期用途和預期的數據類型。
請不要聲明數值、字符串或布爾對象
請始終將數值、字符串或布爾值視作原始值。而非對象。
如果把這些類型聲明為對象,會拖慢執行速度,并產生討厭的副作用:
實例
var x = "Bill"; var y = new String("Bill"); (x === y) // 結果為 false,因為 x 是字符串,而 y 是對象。
或者甚至更糟:
實例
var x = new String("Bill"); var y = new String("Bill"); (x == y) // 結果是 false,因為你無法比較對象。
請勿使用 new Object()
- 請使用 {} 來代替 new Object()
- 請使用 "" 來代替 new String()
- 請使用 0 來代替 new Number()
- 請使用 false 來代替 new Boolean()
- 請使用 [] 來代替 new Array()
- 請使用 /()/ 來代替 new RegExp()
- 請使用 function (){}來代替 new Function()
實例
var x1 = {}; // 新對象 var x2 = ""; // 新的原始字符串值 var x3 = 0; // 新的原始數值 var x4 = false; // 新的原始布爾值 var x5 = []; // 新的數組對象 var x6 = /()/; // 新的正則表達式 var x7 = function(){}; // 新的函數對象
意識到自動類型轉換
請意識到數值會被意外轉換為字符串或 NaN
(Not a Number)。
JavaScript 屬于松散類型。變量可包含不同的數據類型,并且變量能夠改變其數據類型:
實例
var x = "Hello"; // typeof x 為字符串 x = 5; // 把 typeof x 更改為數值
如果進行數學運算,JavaScript 能夠將數值轉換為字符串:
實例
var x = 5 + 7; // x.valueOf() 是 12, typeof x 是數值 var x = 5 + "7"; // x.valueOf() 是 57, typeof x 是字符串 var x = "5" + 7; // x.valueOf() 是 57, typeof x 是字符串 var x = 5 - 7; // x.valueOf() 是 -2, typeof x 是數值 var x = 5 - "7"; // x.valueOf() 是 -2, typeof x 是數值 var x = "5" - 7; // x.valueOf() 是 -2, typeof x 是數值 var x = 5 - "x"; // x.valueOf() 是 NaN, typeof x 是數值
用字符串減去字符串,不會產生錯誤而是返回 NaN
(Not a Number):
實例
"Hello" - "Dolly" // 返回 NaN
使用 === 比較
==
比較運算符總是在比較之前進行類型轉換(以匹配類型)。
===
運算符會強制對值和類型進行比較:
實例
0 == ""; // true 1 == "1"; // true 1 == true; // true 0 === ""; // false 1 === "1"; // false 1 === true; // false
使用 Parameter Defaults
如果調用函數時缺少一個參數,那么這個缺失參數的值會被設置為 undefined
。
undefined
值會破壞您的代碼。為參數設置默認值是一個好習慣。
實例
function myFunction(x, y) { if (y === undefined) { y = 0; } }
請在函數參數這一章閱讀更多有關函數參數的內容。
用 default 來結束 switch
請使用 default
來結束您的 switch
語句。即使您認為沒有這個必要。
實例
switch (new Date().getDay()) { case 0: day = "Sunday"; break; case 1: day = "Monday"; break; case 2: day = "Tuesday"; break; case 3: day = "Wednesday"; break; case 4: day = "Thursday"; break; case 5: day = "Friday"; break; case 6: day = "Saturday"; break; default: day = "Unknown"; }
避免使用 eval()
eval()
函數用于將文本作為代碼來允許。在幾乎所有情況下,都沒有必要使用它。
因為允許任意代碼運行,它同時也意味著安全問題。