所有的块语句都应当使用花括号, 包括:
- if
- for
- while
- do…while…
- try…catch…finally
3.1 花括号的对齐方式
// 第一种 java风格
if(condition) {
doSomething();
}else {
doSomethingElse();
}
// 第二种 C#风格
if(condition) {
doSomething();
}
else
{
doSomethingElse();
}
3.2 块语句间隔
// 第一种 在语句名、圆括号和左花括号之间没有空格间隔
if(condition){
doSomething();
}
// 第二种 在左圆括号之前和右圆括号之后各添加一个空格
if (condition) {
doSomething();
}
// 第三种 在左圆括号后和右圆括号前各添加一个空格
if ( condition ) {
doSomething();
}
// 我个人喜欢 在右括号之后添加一个空格
if(condition) {
doSomething();
}
我认为我的这种写法不仅看起来紧凑而且对于条件判断也更易读. 第二种风格也是用的很广泛,这种风格是第一种和第三种的折衷.
3.3 switch语句
源自C, 但是Java和Javascript中又没有完全相同的语法. js中的switch语句和其他语言是不一样的: switch语句中可以使用任意类型值, 任何表达式都可合法的用于case从句. 但在其他语言中则必须使用原始值和常量.
3.3.1 缩进
大体分为两种格式:
// 第一种 个人倾向于这种
switch(condition) {
case 'first':
// 代码
break;
case 'second':
// 代码
break;
case 'third':
// 代码
break;
default:
// 代码
}
// 第二种 Crockford的编程规范和Dojo编程风格指南提倡
switch(condition) {
case 'first':
// 代码
break;
case 'second':
// 代码
break;
case 'third':
// 代码
break;
default:
// 代码
}
3.3.2 case语句的”连续执行”
switch(condition) {
// 明显的依次执行
case 'first':
case 'second':
// 代码
break;
case 'third':
// 代码
break;
default:
// 代码
}
只要是有意为之并且添加了注释的, 就可以使用case语句的连续执行.
3.3.3 default
是否需要default.
// 第一种 不应该省略default, 哪怕毛事没有.
switch(condition) {
case 'first':
// 代码
break;
case 'second':
// 代码
break;
default:
// default中没有逻辑
}
// 第二种 没有默认行为且写了注释的情况下省略default 个人倾向于这种
switch(condition) {
case 'first':
// 代码
break;
case 'second':
// 代码
break;
// 没有default
}
3.4 with语句
with语句可以更改包含的上下文解析变量的方式. 通过with可以用局部变量和函数的形式来访问特定对象的属性和方法, 这样就可以将对象前缀统统省略掉.如果一段代码中写了很多对象的成员, 则可以使用with语句来缩短这段代码.
var book = {
title: '编写可维护的js',
author: 'Nicholas'
};
var message = 'The book is ';
with(book) {
message += title;
message += ' by ' + author;
}
这个例子中, with语句花括号内的代码中的book属性都是通过局部变量来读取的,
3.5 for循环
有两种方法可以更改循环的执行过程(除了使用return或throw语句). 第一种方法是使用break语句. 不管所有的循环迭代有没有执行完毕, 使用break总是可以立即退出循环.
var values = [1, 2, 3, 4, 5];
for(var i = 0; i <= values.length; i++) {
if(i == 2) {
break; // 迭代不会继续
}
process(values[i]);
}
这个循环执行两次, 在第三次执行process()之前就终止循环了.
第二种更改循环执行过程的方法是使用continue. continue语句可以立即退出(本次)循环, 而进入下一次循环迭代.
var values = [1, 2, 3, 4, 5];
for(var i = 0; i <= values.length; i++) {
if(i == 2) {
continue; // 跳过本次迭代
}
process(values[i]);
}
这里的循环执行两次, 跳过第三次直接进入第四次, 然后一直执行到最后一次.
Crockford的编程规范不允许使用continue, 主张与其使用continue不如使用条件语句. 上面的例子可以修改成这样.
var values = [1, 2, 3, 4, 5];
for(var i = 0; i <= values.length; i++) {
if(i != 2) {
process(values[i]);
}
}
推荐尽可能避免使用continue, 使用应当根据代码的可读性来决定.
3.6 for-in循环
for-in遍历对象属性. 返回属性名.
for-in有个问题, 不仅遍历对象的实例属性, 还会遍历出来从原型继承来的属性. 当遍历自定义对象的属性时, 往往会因为意外的结果而终止. 由于这样最好使用hasOwnProperty()方法来为for-in循环出实例属性.
// 不遍历从原型继承来的属性
for(var prop in object){
if(object.hasOwnProperty(prop)) {
console.log('Property name is ' + prop);
console.log('Property value is ' + object[prop]);
}
}
// 包含遍历从原型继承来的属性
for(var prop in object){
console.log('Property name is ' + prop);
console.log('Property value is ' + object[prop]);
}
// 最好不要用for-in来遍历数组 会有潜在的错误
var items= [1, 2, 3, 4, 5];
for(var i in items){
process(items[i]);
}