JavaScript 最佳实践

请避免全局变量、new、===、eval()

避免全局变量

请尽量少地使用全局变量。

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

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

请使用局部变量替代,并学习如何使用闭包

始终声明局部变量

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

局部变量必须通过 var 关键词来声明,否则它们将变成全局变量。

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

在顶部声明

一项好的编码习惯是把所有声明放在每段脚本或函数的顶部。

这么做的好处是:

  • 获得更整洁的代码
  • 提供了查找局部变量的好位置
  • 更容易避免不需要的全局变量
  • 减少不需要的重新声明的可能性
  1. // 在顶部声明
  2. var firstName, lastName, price, discount, fullPrice;
  3.  
  4. // 稍后使用
  5. firstName = "Bill";
  6. lastName = "Gates";
  7.  
  8. price = 19.90;
  9. discount = 0.10;
  10.  
  11. fullPrice = price * 100 / discount;

也可以用于循环变量:

  1. // 在顶部声明
  2. var i;
  3.  
  4. // 稍后使用
  5. for (i = 0; i < 5; i++) {

默认地,JavaScript 会将所有声明移至顶部(JavaScript hoisting)。

初始化变量

在您声明变量时对其进行初始化是个好习惯。

这么做的好处是:

  • 更整洁的代码
  • 在单独的位置来初始化变量
  • 避免未定义值
  1. // 在开头进行声明和初始化
  2. var firstName = "",
  3. lastName = "",
  4. price = 0,
  5. discount = 0,
  6. fullPrice = 0,
  7. myArray = [],
  8. myObject = {};

变量初始化使我们能够了解预期用途和预期的数据类型。

请不要声明数值、字符串或布尔对象

请始终将数值、字符串或布尔值视作原始值。而非对象。

如果把这些类型声明为对象,会拖慢执行速度,并产生讨厌的副作用:

实例

  1. var x = "Bill";
  2. var y = new String("Bill");
  3. (x === y) // 结果为 false,因为 x 是字符串,而 y 是对象。

或者甚至更糟:

实例

  1. var x = new String("Bill");
  2. var y = new String("Bill");
  3. (x == y) // 结果是 false,因为你无法比较对象。

请勿使用 new Object()

  • 请使用 {} 来代替 new Object()
  • 请使用 "" 来代替 new String()
  • 请使用 0 来代替 new Number()
  • 请使用 false 来代替 new Boolean()
  • 请使用 [] 来代替 new Array()
  • 请使用 /()/ 来代替 new RegExp()
  • 请使用 function (){}来代替 new Function()

实例

  1. var x1 = {}; // 性象
  2. var x2 = ""; // 新的原始字符串值
  3. var x3 = 0; // 新的原始数值
  4. var x4 = false; // 新的原始布尔值
  5. var x5 = []; // 新的数组对象
  6. var x6 = /()/; // 新的正则表达式
  7. var x7 = function(){}; // 新的函数对象

意识到自动类型转换

请意识到数值会被意外转换为字符串或 NaN(Not a Number)。

JavaScript 属于松散类型。变量可包含不同的数据类型,并且变量能够改变其数据类型:

实例

  1. var x = "Hello"; // typeof x 为字符串
  2. x = 5; // 把 typeof x 更改为数值

如果进行数学运算,JavaScript 能够将数值转换为字符串:

实例

  1. var x = 5 + 7; // x.valueOf() 是 12, typeof x 是数值
  2. var x = 5 + "7"; // x.valueOf() 是 57, typeof x 是字符串
  3. var x = "5" + 7; // x.valueOf() 是 57, typeof x 是字符串
  4. var x = 5 - 7; // x.valueOf() 是 -2, typeof x 是数值
  5. var x = 5 - "7"; // x.valueOf() 是 -2, typeof x 是数值
  6. var x = "5" - 7; // x.valueOf() 是 -2, typeof x 是数值
  7. var x = 5 - "x"; // x.valueOf() 是 NaN, typeof x 是数值

用字符串减去字符串,不会产生错误而是返回 NaN(Not a Number):

实例

  1. "Hello" - "Dolly" // 返回 NaN

使用 === 比较

== 比较运算符总是在比较之前进行类型转换(以匹配类型)。

=== 运算符会强制对值和类型进行比较:

实例

  1. 0 == ""; // true
  2. 1 == "1"; // true
  3. 1 == true; // true
  4.  
  5. 0 === ""; // false
  6. 1 === "1"; // false
  7. 1 === true; // false

使用 Parameter Defaults

如果调用函数时缺少一个参数,那么这个缺失参数的值会被设置为 undefined。

undefined 值会破坏您的代码。为参数设置默认值是一个好习惯。

实例

  1. function myFunction(x, y) {
  2. if (y === undefined) {
  3. y = 0;
  4. }
  5. }

请在函数参数这一章阅读更多有关函数参数的内容。

用 default 来结束 switch

请使用使用 default 来结束您的 switch 语句。即使您认为没有这个必要。

实例

  1. switch (new Date().getDay()) {
  2. case 0:
  3. day = "Sunday";
  4. break;
  5. case 1:
  6. day = "Monday";
  7. break;
  8. case 2:
  9. day = "Tuesday";
  10. break;
  11. case 3:
  12. day = "Wednesday";
  13. break;
  14. case 4:
  15. day = "Thursday";
  16. break;
  17. case 5:
  18. day = "Friday";
  19. break;
  20. case 6:
  21. day = "Saturday";
  22. break;
  23. default:
  24. day = "Unknown";
  25. }

避免使用 eval()

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

因为允许任意代码运行,它同时也意味着安全问题。