JavaScript 最佳實踐
避免全域性變數,避免使用 new
,避免使用 ==
,避免使用 eval()
避免全域性變數
儘量少用全域性變數。
包括所有資料型別、物件和函式。
全域性變數和函式可能被其他指令碼覆蓋。
改用區域性變數,並學習如何使用 閉包。
始終宣告區域性變數
函式中使用的所有變數都應宣告為區域性變數。
區域性變數必須使用 var
、let
或 const
關鍵字宣告,否則它們將成為全域性變數。
嚴格模式不允許使用未宣告的變數。
宣告放在頂部
將所有宣告放在每個指令碼或函式的頂部是一個良好的編碼實踐。
這將
- 使程式碼更整潔
- 提供一個查詢區域性變數的單一位置
- 更容易避免意外的(隱式)全域性變數
- 減少意外重新宣告的可能性
// 在開頭宣告
let firstName, lastName, price, discount, fullPrice;
// 稍後使用
firstName = "John";
lastName = "Doe";
price = 19.90;
discount = 0.10;
fullPrice = price - discount;
這同樣適用於迴圈變數
for (let i = 0; i < 5; i++) {
初始化變數
在宣告變數時初始化它們是一個良好的編碼實踐。
這將
- 使程式碼更整潔
- 提供一個初始化變數的單一位置
- 避免未定義的值
// 在開頭宣告並初始化
let firstName = "";
let lastName = "";
let price = 0;
let discount = 0;
let fullPrice = 0,
const myArray = [];
const myObject = {};
初始化變數可以說明其預期用途(和預期資料型別)。
使用 const 宣告物件
使用 const 宣告物件可以防止意外的型別更改
示例
let car = {type:"Fiat", model:"500", color:"white"};
car = "Fiat"; // 將物件更改為字串
const car = {type:"Fiat", model:"500", color:"white"};
car = "Fiat"; // 不可能
使用 const 宣告陣列
使用 const 宣告陣列可以防止意外的型別更改
示例
let cars = ["Saab", "Volvo", "BMW"];
cars = 3; // 將陣列更改為數字
const cars = ["Saab", "Volvo", "BMW"];
cars = 3; // 不可能
不要使用 new Object()
- 使用
""
而不是new String()
- 使用
0
而不是new Number()
- 使用
false
而不是new Boolean()
- 使用
{}
而不是new Object()
- 使用
[]
而不是new Array()
- 使用
/()/
而不是new RegExp()
- 使用
function (){}
而不是new Function()
示例
let x1 = ""; // 新的原生字串
let x2 = 0; // 新的原生數字
let x3 = false; // 新的原生布爾值
const x4 = {}; // 新物件
const x5 = []; // 新陣列物件
const x6 = /()/; // 新的正則表示式物件
const x7 = function(){}; // 新函式物件
自己動手試一試 »
注意自動型別轉換
JavaScript 是弱型別語言。
一個變數可以包含所有資料型別。
一個變數可以改變其資料型別
請注意,數字可能會意外地轉換為字串或 NaN
(非數字)。
在進行數學運算時,JavaScript 可能會將數字轉換為字串
示例
let x = 5 + 7; // x.valueOf() 是 12,typeof x 是 number
let x = 5 + "7"; // x.valueOf() 是 57,typeof x 是 string
let x = "5" + 7; // x.valueOf() 是 57,typeof x 是 string
let x = 5 - 7; // x.valueOf() 是 -2,typeof x 是 number
let x = 5 - "7"; // x.valueOf() 是 -2,typeof x 是 number
let x = "5" - 7; // x.valueOf() 是 -2,typeof x 是 number
let x = 5 - "x"; // x.valueOf() 是 NaN,typeof x 是 number
自己動手試一試 »
字串減去字串不會產生錯誤,但會返回 NaN
(非數字)
使用 === 比較
==
比較運算子在比較之前總是進行型別轉換(以匹配型別)。
===
運算子強制進行值和型別的比較
示例
0 == ""; // true
1 == "1"; // true
1 == true; // true
0 === ""; // false
1 === "1"; // false
1 === true; // false
自己動手試一試 »
使用引數預設值
如果一個函式呼叫時缺少引數,則缺失的引數值被設定為 undefined
。
未定義的值可能會破壞您的程式碼。為引數分配預設值是一個好習慣。
ECMAScript 2015 允許在函式定義中使用預設引數
function (a=1, b=1) { /*function code*/ }
在 函式引數 中閱讀更多關於函式引數和實參的資訊
在 Switch 語句末尾新增 Default
始終在您的 switch
語句末尾新增 default
。即使您認為沒有必要。
示例
switch (new Date().getDay()) {
case 0
day = "星期日";
break;
case 1
day = "星期一";
break;
case 2
day = "Tuesday";
break;
case 3
day = "星期三";
break;
case 4
day = "Thursday";
break;
case 5
day = "Friday";
break;
case 6
day = "Saturday";
break;
default
day = "Unknown";
}
自己動手試一試 »
避免將數字、字串和布林值用作物件
始終將數字、字串或布林值視為原始值。而不是物件。
將這些型別宣告為物件會減慢執行速度,併產生棘手的副作用
或者更糟糕
避免使用 eval()
eval()
函式用於將文字作為程式碼執行。在幾乎所有情況下,都不需要使用它。
因為它允許執行任意程式碼,所以它也代表著安全問題。