JavaScript 最佳实践

JavaScript 最佳实践整理了一些好的编码习惯,有助于减少程序错误。

JavaScript 最佳实践整理了一些好的编码习惯,有助于减少程序错误。

避免全局变量,避免 new ,避免 == ,避免 eval()

避免全局变量

尽量减少使用全局变量。

这包括所有数据类型、对象和函数。

全局变量和函数可以被其他脚本覆盖。

改用局部变量,并学习如何使用 闭包

始终声明局部变量

函数中使用的所有变量都应声明为局部变量。

局部变量必须var 关键字或 let 关键字声明,否则会成为全局变量。

严格模式不允许未声明的变量。

顶部声明

将所有声明放在每个脚本或函数的顶部是一种很好的编码习惯。

这会:

  • 提供更清晰的代码
  • 提供一个地方来查找局部变量
  • 更容易避免不需要的(隐含的)全局变量
  • 减少不必要的重新声明的可能性
// 在开头声明变量
let firstName, lastName, price, discount, fullPrice;

// 稍后使用变量
firstName = "John";
lastName = "Doe";

price = 19.9;
discount = 0.1;

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"; // 报错

使用 onst 声明数组

使用 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 是松散类型的。

一个变量可以包含所有数据类型。

一个变量可以改变它的数据类型:

let x = "Hello"; // typeof x 是 string
x = 5; // 修改后 typeof x 是 number

请注意,数字可能会意外转换为字符串或 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 (非数字):

"Hello" - "Dolly"; // 返回 NaN

使用 === 比较

===== 更加严格,不但比较值,也比较类型。

0 == ""; // true
1 == "1"; // true
1 == true; // true
0 === ""; // false
1 === "1"; // false
1 === true; // false

使用参数默认值

如果调用函数时缺少参数,则缺少参数的值将设置为 undefined

未定义的值可能会破坏您的代码。为参数分配默认值是一个好习惯。

function myFunction(x, y) {
  if (y === undefined) {
    y = 0;
  }
}

ECMAScript 2015 允许在函数定义中使用默认参数:

function (a=1, b=1) { /*function code*/ }

函数参数中阅读有关函数参数和参数的更多信息

用默认值结束 switch

switch 始终以 default 结束,即使你认为没有必要。

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";
}

避免将数字、字符串和布尔值作为对象

始终将数字、字符串或布尔值视为原始值。不作为对象。

将这些类型声明为对象,会降低执行速度,并产生令人讨厌的副作用:

let x = "John";
let y = new String("John");
x === y; // 返回 false,因为 x 是 string 而 y 是 object

或者更糟:

let x = new String("John");
let y = new String("John");
x == y; // 返回 false 因为比较对象的时候是比较变量应用的内存地址

避免使用 eval()

eval() 函数用于将文本作为代码运行。在几乎所有情况下,都没有必要使用它。

因为它允许运行任意代码,所以它也可能引入安全问题。