几个值得注意和学习的地方,平时很少考虑,这里做一个小结。

1. 常量

JavaScript目前还没有常量这个概念,只能用大写在视觉上区分:

var MAX_COUNT = 10;

2. null 不适合的场景

(1) 不要使用 null 来检测是否传入了某个参数

(2) 不要用 null 来检测一个未初始化的变量

好的用法:

var person = null;

function getPerson() {

 if (condition){

   reutrn new Person("Nicholas");

 } else {

   return null;

 }

}

var person = getPerson();

if (person !== null) {

 doSomething();

}

不好的写法:检测是否传入了参数

function doSomething(arg1, arg2, arg3, arg4) {

 if (arg4 != null) {

   doSomethingElse();

 }

}

3. undefined

这是一个特殊值。null == undefined 返回 true,但这两个值的用途各不相同。没有被初始化的变量都有一个初始值,即 undefined,这示这个变量等待被赋值。

不好的写法:

var person;

console.log(person === undefined); // true

避免在代码中使用 undefined。

//好的做法

var person = null;

console.log(person === null); // true

4. 使用注释的原则

(1) 难于理解的代码

(2) 可能被误认为错误的代码

(3) 浏览器特性 hack

使用 JSDoc Toolkit 或 YUIDoc 可以把文档注释(JavaDoc风格)生成文档。

5. 分号和花括号

如果不使用分号,JavaScript引擎会进行分号自动插入,这可能会导致错误,所以要求必须使用分号。另外分号的使用,最好把左花括号放在代码的末尾,而不是另起一行,这也是为了防止分号自动插入的好办法。

6. for-in 循环

for-in循环会遍历对象的所有属性,包括从原型继承来的属性,因此最好配合 hasOwnProperty() 方法使用:

var prop;

for (prop in object) {

 if (object.hasOwnProperty(prop)) {

   console.log("Property name is " + prop);

   console.log("Property value is " + object[prop]);

 }

}

还要注意,for-in循环是用来遍历对象的,用于遍历数组成员是错误的用法 。

7. 变量声明

变量声明使用 var 语句完成。var 语句几乎可以用在 JavaScript 脚本的任意地方。不论 var 语句是否真正会被执行,所有的 var 语句都提前到包含这段逻辑的函数的顶部执行

function doSomething() {

 var result = 10 + value;

 var value = 10;

 return result;

}

会被 JavaScript 理解为:

function doSomething() {

 var result;

 var value;

 result = 10 + value;

 value = 10;

 return result;

}

由于 value 的值是 undefined,因此 result 的值是 NaN。

在 ECMAScript5 之前,JavaScript 中并没有块级变量声明。

function doSomethingWithItems(items) {

 for (var i=0, len=items.length; i<len; i<len; i++) {

   doSomething(items[i]);

 }

}

等价于:

function doSomethingWithItems(items) {

 var i, len;

 for (i=0,len=items.length; i<len; i++) {

   doSomething(items[i]);

 }

}

因此,建议总是将局部变量的定义作为函数的第一条语句,Crockford 还推荐使用单 var 语句。

8. 函数声明

函数声明也会提前,因此在函数定义前调用该函数的代码是可以正常运行的。但推荐先声明函数再调用。

9. 立即调用的函数

为了能够一眼看出来,推荐使用圆括号将立即调用的函数包裹起来。

// 好的写法

var value = (function() {

 return {

   message: "Hi"

 }

}());

10. 严格模式

ECMAScript5 引入了“严格模式”(strict mode),指令如下:

"use strict";

不推荐在全局作用域中使用严格模式,因为这会让文件中的所有代码都以严格模式来解析,这可能会让其他文件中的(非严格模式)代码报错。

// 好的写法

function doSomething() {

 "use strict";

 // code

}

11. 相等

== 和 != 在比较的两个值的类型不同时,会自动进行类型转换后再比较。这会导致意外的结果。

console.log(5 == "5"); // true,字符串和数字比较,字符串被转换为数字

console.log(25 == "0x19"); // true

console.log(1 == true); // true,布尔值和数字比较,布尔值被转换为数字

console.log(0 == false); // true,false转为0,true转为1

console.log(2 == true); // false

如果其中一值是对象而另一个不是,则会首先调用对象的 valueOf() 方法,得到原始类型值再进行比较。如果没有定义 vlaueOf(),则调用 toString()。

var object = {

 toString: function() {

   return "0x19";

 }

};

console.log(object == 25); // true

根据ECMAScript标准规范,null 和 undefined 是相等的。

console.log(null == undefined); // true

不推荐使用 == 和 !=,而应当使用 === 和 !==,不会涉及强制类型转换,如果两个值的类型不一样,则认为不相等。

12. eval()

严禁使用 Function,在别无他法时使用 eval()。setTimeout()和setInterval()可以使用,但不要用字符串形式而要用函数。

13. 原始包装类型

3种:String、Boolean 和 Number。主要作用是让原始值具有对象般的行为。

var name = "Nicholas";

console.log(name.toUpperCase());

JavaScript引擎创建了String类型的新实例,紧跟着就销毁了。

var name = "Nicholas";

name.author = true;

console.log(name.author); // undefined

在第2行结束后,author属性就不见了。

// 不好的做法

var name = new String("Nicholas");

var author = new boolean(true);

var count = new Number(10);

强烈建议避免使用它们。

14. JSLint 和 JSHint

最后,作为代码风格的检测工具,推荐使用这两个工具,选择使用其中一个就可以了。