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 是数字
let x = 5 + "7"; // x.valueOf() 是 57,typeof x 是字符串
let x = "5" + 7; // x.valueOf() 是 57,typeof x 是字符串
let x = 5 - 7; // x.valueOf() 是 -2,typeof x 是数字
let x = 5 - "7"; // x.valueOf() 是 -2,typeof x 是数字
let x = "5" - 7; // x.valueOf() 是 -2,typeof x 是数字
let x = 5 - "x"; // x.valueOf() 是 NaN,typeof x 是数字
自己尝试 »
从字符串中减去字符串不会产生错误,但会返回 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) { /*函数代码*/ }
有关函数参数和参数的更多信息,请阅读 函数参数
在 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";
}
自己尝试 »
避免使用 Number、String 和 Boolean 作为对象
始终将数字、字符串或布尔值视为原始值。而不是对象。
将这些类型声明为对象会降低执行速度,并产生令人讨厌的副作用
更糟糕的是
避免使用 eval()
eval()
函数用于将文本作为代码运行。在几乎所有情况下,都不应该使用它。
因为它允许运行任意代码,因此它也代表了一个安全问题。