几个值得注意和学习的地方,平时很少考虑,这里做一个小结。
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
最后,作为代码风格的检测工具,推荐使用这两个工具,选择使用其中一个就可以了。