JavaScript最佳实践



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


避免使用全局变量

尽量减少全局变量的使用.

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

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

使用本地变量,并学习如何使用闭包.


总是声明局部变量

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

局部变量必须用var关键字声明,否则将成为全局变量.

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


声明在顶部

将所有声明放在每个脚本或函数的顶部是一个很好的编码实践.

好处:

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

// Use later
firstName = "John";
lastName = "Doe";

price = 19.90;
discount = 0.10;

fullPrice = price * 100 / discount;

这也用于循环变量:

// Declare at the beginning
var i;

// Use later
for (i = 0; i < 5; i++) {

默认情况下,所有声明的JavaScript移到顶部 (JavaScript hoisting).


初始化变量

这是一个很好的编码习惯当你声明变量是初始化他们.

好处:

  • 代码清晰
  • 提供一个初始化变量的地方
  • 避免未定义值
// Declare and initiate at the beginning
var firstName = "",
    lastName = "",
    price = 0,
    discount = 0,
    fullPrice = 0,
    myArray = [],
    myObject = {};

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

总是把数字、字符串、布尔值作为原始值对待。而不是对象.

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

var x = "John";             
var y = new String("John");
(x === y) // is false because x is a string and y is an object.

让我试试

甚至更糟:

var x = new String("John");             
var y = new String("John");
(x == y) // is false because you cannot compare objects.

让我试试


不要使用 new Object()

  • 使用{} 代替 new Object()
  • 使用 "" 代替 new String()
  • 使用 0 代替 new Number()
  • 使用 false 代替 new Boolean()
  • 使用 [] 代替 new Array()
  • 使用 /()/ 代替 new RegExp()
  • 使用 function (){} 代替 new Function()
var x1 = {};           // new object
var x2 = "";           // new primitive string
var x3 = 0;            // new primitive number
var x4 = false;        // new primitive boolean
var x5 = [];           // new array object
var x6 = /()/;         // new regexp object
var x7 = function(){}; // new function object

让我试试


小心自动类型转换

小心数字可以意外地转换为字符串或 NaN (Not a Number).

JavaScript 是弱类型语言. 变量可以包含不同的数据类型,变量可以改变数据类型:

var x = "Hello";     // typeof x is a string
x = 5;               // changes typeof x to a number

让我试试

当你做数学运算是,JavaScript可以转换数字为字符串:

var x = 5 + 7;       // x.valueOf() is 12,  typeof x is a number
var x = 5 + "7";     // x.valueOf() is 57,  typeof x is a string
var x = "5" + 7;     // x.valueOf() is 57,  typeof x is a string
var x = 5 - 7;       // x.valueOf() is -2,  typeof x is a number
var x = 5 - "7";     // x.valueOf() is -2,  typeof x is a number
var x = "5" - 7;     // x.valueOf() is -2,  typeof x is a number
var x = 5 - "x";     // x.valueOf() is NaN, typeof x is a number

让我试试

从字符串中减去字符串,不生成错误,但返回 NaN (Not a Number):

"Hello" - "Dolly"    // returns NaN

让我试试


使用 === 比较

== 比较运算符总是在比较之前转换(匹配类型).

=== 强制比较值和类型:

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

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

让我试试


使用默认参数

如果函数使用缺少的参数调用,则缺少参数的值将设置为未定义.

未定义值可以终止你的代码. 给参数分配默认值是一个好习惯.

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

让我试试

Read more about function parameters and arguments at Function Parameters


在switch中使用default

总是在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";
}

让我试试


避免使用 eval()

eval() 函数用于将文本作为代码运行。在几乎所有的情况下,它不应该使用它。

因为它允许任意代码运行,它也代表了安全问题.