第一部分 编程风格
第3章 语句和表达式
在JavaScript中,如if和for之类的语句有两种写法,一种是使用花括号包裹的多行代码,另一种是不使用花括号的单行代码。比如:
// 不好的写法,尽管这是合法的JavaScript代码
if(condition)
doSomething();
// 不好的写法,尽管是合法的JavaScript代码
if(condition) doSomething();
// 好的写法
if (condition) {
doSomething()
}
// 不好的写法,尽管是合法的JavaScript代码
if (condition) { doSomething() }
不论块语句包含多行代码还是单行代码,都应当总是使用花括号,因为省略花括号会造成一些困惑。
所有块语句都应当使用花括号,包括:
- if
- for
- while
- do...while...
- try...catch...finally
3.1 花括号的对齐方式
花括号的对齐风格,主要有两种。一种是将左花括号放置在块语句中第一句代码的末尾,比如:
if (condition) {
doSomething();
} else {
doSomethingElse();
}
另一种风格是将做花括号放置于块语句首行的下一行。比如:
if (condition)
{
doSomething();
}
else
{
doSomethingElse();
}
作者个人推荐使用第一种。
3.2 块语句间隔
块语句间隔主要有三种风格。第一种风格是,在语句名、圆括号和左花括号之间没有空格间隔。
if(condition){
doSomething();
}
第二种风格是,在括左圆括号之前和右圆括号之后各添加一个空格,比如:
if (condition) {
doSomething();
}
第三种风格是在做圆括号后和右圆括号前各添加一个空格,比如:
if ( condition ) {
doSomething()
}
作者推荐第二种风格,这种风格是第一种和第三种风格的折中。
3.3 switch语句
3.3.1 缩进
switch(condition) {
case "first":
// 代码
break;
case "second":
// 代码
break;
case "third":
// 代码
break;
default:
// 代码
}
以上这种风格的特点有:
- 每条case语句相对于switch关键字都缩进一个层级。
- 从第二条case语句开始,每条case语句前后各有一个空行。
另一种风格:
switch(condition) {
case "first":
// 代码
break;
case "second":
// 代码
break;
case "third":
// 代码
break;
default:
// 代码
}
这种写法与前一种写法的主要不用之处在于,case关键字保持和switch关键在左对齐,并且没有空行的存在。
3.3.2 case语句的“连续执行”
swith(condition) {
// 明显的依次执行
case "first":
case "second":
// 代码
break;
case "third":
// 代码
/* fall through */
default:
// 代码
}
在这段switch语句中,有两个明显的“连续执行”,程序执行完第一个case后会继续执行第二个case,我们认为这种逻辑是合理的。
第二个例子是case third执行后继续执行default里的逻辑。这个过程已经在注释中明确说明了,这是程序编写者故意为之。
作者建议,只要是有意为之并且添加了注释,就可以使用case语句的连续执行。
3.3.3 default
很多人认为不论何时都不应该省略default,哪怕default什么也不做。
作者更倾向于在没有默认行为并且写了注释的情况下省略default:
switch(condition) {
case "first":
// 代码
break;
case "second":
// 代码
break;
// 没有default
}
3.4 with语句
with语句可以更改包含的上下文解析变量的方式,通过with可以用局部变量和函数的形式来访问特定对象的属性和方法,这样就可以将对象前缀统统省略掉。
在严格模式中,with语句是被明确禁止的,作者也强烈推荐避免使用with语句。
3.5 for循环
for循环有两种一种是传统的for循环,另一种是for-in循环。
传统的for循环往往用于遍历数组成员,有两种方法可以更改循环的执行过程(除了使用return或throw语句)。第一种方法是使用break语句,立即退出循环,第二种是使用continue,使用continue可以立即退出(本次)循环,而进入下一次循环迭代。
Crockford的编程规范不允许使用continue。他主张代码中与其使用continue不如使用条件语句。
作者推荐尽可能避免使用continue,但也没有理由完全禁止使用,它的使用应当根据代码可读性来决定。
当使用了continue时,JSLint会给出警告,而JSHint不会给出警告。
3.6 for-in循环
for-in循环是用来遍历对象属性的。
for-in循环有一个问题,就是它不仅遍历对象的实例属性,同样还遍历从原型继承来的属性。当遍历自定义对象的属性时,往往会因为意外的结果而终止。出于这个原因,最好使用hasOwnProperty()方法来为for-in循环过滤出实例属性。
var prop;
for (prop in object) {
if (object.hasOwnProperty(prop)) {
console.log("Property name is" + prop);
console.log("Property value is" + object[prop]);
}
}
Crockford的编程规范要求所有的for-in循环都必须使用hasOwnProperty()。默认情况下,对于循环体中没有使用hasOwnProperty()的for-in循环,JSLint和JSHint都会给出警告。
作者推荐总是在for-in循环中使用hasOwnProperty(),除非你想查找原型链,这是就应当补充注释。
关于for-in循环,还有一点需要注意,即for-in循环是用来遍历对象的,一个常见的错误用法是使用for-in循环来遍历数组成员。