编程风格 - 第 3 章 语句和表达式
《编写可维护的 JavaScript》—— Nicholas C. Zakas
所有的块语句(block statement)都应当使用花括号,包括:
- if
- for
- while
- do…while…
- try…catch…finally
省略花括号会造成一些困惑,如下
if (condition)
doSomething();
doSomethingElse();
这段代码很难看出作者的真正意图:是缩进错误,还是丢失了花括号?
如果添加了花括号,就能很容易排除错误,如下
// 缩进错误
if (condition){
doSomething();
}
doSomethingElse();
if (condition){
doSomething();
doSomethingElse();
}
即使代码块只有一行代码也要用花括号包裹
// 不好的写法
if (condition)
doSomething();
// 不好的写法
if (condition) doSomething();
// 不好的写法
if (condition) { doSomething(); }
// 好的写法
if (condition) {
doSomething();
}
1. 花括号的对齐方式
主要有两种花括号对齐风格。
第一种,左花括号与首行代码同行,这种风格继承自 Java,如下
if (condition) {
doSomething();
} else {
doSomethingElse();
}
第二种,左花括号独占一行,这种风格随着 C# 流行起来的,因为 Visual Studio 强制使用这种对齐方式。
但前没有主流的 JavaScript 编程规范推荐这种风格,因为会导致错误的分号自动插入。
if (condition)
{
doSomething()
}
else
{
doSomethingElse();
}
2. 块语句间隔
块语句首行中的间隔是需要考虑的,有三种主要的间隔分隔。
// 紧凑型:表达式、圆括号、花括号之间都没有空格
if(condition){
doSomething();
}
// 宽松型:表达式、圆括号、花括号之间都有空格。(jQuery 风格)
if ( condition ) {
doSomething();
}
// 折中型:小括号左右各一个空格。(用得最多)
if (condition) {
doSomething();
}
3. switch 语句
JavaScript 中的 switch 语句的行为和其他语言不一样:switch 语句中可以使用任意类型值。
3.1. 缩进
Java 风格的 switch 语句:
switch(condition) {
case 'first':
// 代码
break;
case 'second':
// 代码
break;
default:
// 代码
}
另一种格式:
switch(condition) {
case 'first':
// 代码
break;
case 'second':
// 代码
break;
default:
// 代码
}
选择哪一种凭个人偏好。
3.2. case 语句的“连续执行”
有意为之,且添加了注释时,允许 fall through。
switch(condition) {
// fall through
case 'first':
case 'second':
// 代码
break;
case 'forth':
// 代码
/* fall through */
case 'fifth':
// 代码
break;
default:
// 代码
}
3.3. default
不论何时都不应该省略 default
,哪怕 default
什么也不做。
4. with 语句
JavaScript 引擎和压缩工具无法对 with
语句进行优化。在严格模式中, with
语句是被明确禁止的。
5. for 循环
不推荐使用 continue
跳过本次迭代,而使用条件语句。
var values = [ 1, 2, 3 ],
i, len;
// 不推荐
for (i = 0, len = values.length; i < len; i++) {
if (i === 2) {
continue;
}
process(values[i]);
}
// 推荐:更易理解且不容易出错
for (i = 0, len = values.length; i < len; i++) {
if (i !== 2) {
process(values[i]);
}
}
6. for-in 循环
for-in 不仅遍历对象的实例属性(instance property),也会遍历从原型继承来的属性。
当遍历自定义对象的属性时,往往会因为意外的结果而终止。
推荐使用 hasOwnProperty()
方法来为 for-in 循环过滤出实例属性。
var prop;
for (prop in object) {
if (object.hasOwnProperty(prop)) {
console.log(prop, object[prop]);
}
}
如果需要遍历原型链,则要补充注释。
不建议用 for-in 遍历数组。