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() 函數用于將文本作為代碼來允許。在幾乎所有情況下,都沒有必要使用它。

因為允許任意代碼運行,它同時也意味著安全問題。