代码规范
确立并遵守代码规范非常重要,这会让你的代码风格一致、可预测,并且可读性更强。团队新成员通过学习代码规范可以很快进入开发状态,并写出让团队其他成员易于理解的代码。
在开源社区和邮件组中关于编代风格的争论一直不断。(比如关于代码缩进,用tab还是空格?)因此,如果你打算在团队内推行某种编码规范时,要做好应对各种反对意见的心理准备,而且要吸取各种意见。确定并遵守代码规范非常重要,任何一种规范都可以,这甚至比代码规范中的具体约定是怎么样的还要重要。
缩进
代码如果没有缩进就几乎不能读了,而不一致的缩进会使情况更加糟糕,因为它看上去像是遵守了规范,但真正读起来却没那么顺利。因此规范地使用缩进非常重要。
有些开发者喜欢使用tab缩进,因为每个人都可以根据自己的喜好来调整tab缩进的空格数,有些人则喜欢使用空格缩进,通常是四个空格。这都无所谓,只要团队每个人都遵守同一个规范即可,本书中所有的示例代码都采用四个空格的缩进写法,这也是JSLint所推荐的。(译注:电子版中看到的是用tab缩进,本译文也保留使用tab缩进。)
那么到底什么时候应该缩进呢?规则很简单,花括号里的内容应当缩进,包括函数体、循环(do
、while
、for
和for-in
)体、if
语句、switch
语句和对象字面量里的属性。下面的代码展示了如何正确地使用缩进:
function outer(a, b) {
var c = 1,
d = 2,
inner;
if (a > b) {
inner = function () {
return {
r: c - d
};
};
} else {
inner = function () {
return {
r: c + d
};
};
}
return inner;
}
花括号
在特定的语句中应当总是使用花括号,即便是在可省略花括号的情况下也应当如此。从技术角度讲,如果if
或for
中只有一个语句,花括号是可以省略的,但最好还是不要省略,这会让你的代码更加工整一致而且易于修改。
假设有这样一段代码,for
循环中只有一条语句,你可以省略掉这里的花括号,而且不会有语法错误:
// 不好的方式
for (var i = 0; i < 10; i += 1)
alert(i);
但如果过了一段时间,你给这个循环添加了另一行代码会怎样?
// 不好的方式
for (var i = 0; i < 10; i += 1)
alert(i);
alert(i + " is " + (i % 2 ? "odd" : "even"));
第二个alert
实际上在循环体之外,但这里的缩进会让你迷惑。从长远考虑最好还是写上花括号,即便是在只有一个语句的语句块中也应如此:
// 更好的方式
for (var i = 0; i < 10; i += 1) {
alert(i);
}
同理,if条件句也应当如此:
// 不好的方式
if (true)
alert(1);
else
alert(2);
// 更好的试
if (true) {
alert(1);
} else {
alert(2);
}
左花括号的位置
开发人员对于左大括号的位置有着不同的偏好,在同一行呢还是在下一行?
if (true) {
alert("It's TRUE!");
}
或者:
if (true)
{
alert("It's TRUE!");
}
在这个例子中,这个问题只是个人偏好问题。但有时候花括号位置的不同会影响程序的执行,因为JavaScript会“自动插入分号”。JavaScript对行尾是否有分号并没有要求,它会自动将分号补全。因此,当函数的return
语句返回了一个对象字面量,而对象的左花括号和return
又不在同一行时,程序的执行就和预期的不同了:
// 警告:返回值和预期的不同
function func() {
return
{
name: "Batman"
};
}
可以看出程序作者的意图是返回一个包含了name
属性的对象,但实际情况不是这样。因为return后会填补一个分号,函数的返回值就是undefined。这段代码等价于:
// 警告:返回值和预期的不同
function func() {
return undefined;
// 下面的代码不会运行…
{
name: "Batman"
};
}
总结一下好的写法,在特写的语句中总是使用花括号,并且总是将左花括号与上一条语句放在同一行:
function func() {
return {
name: "Batman"
};
}
关于分号也值得注意:和花括号一样,应当总是使用分号,尽管在JavaScript解析代码时会补全行末省略的分号,但严格遵守这条规则,可以让代码更加严谨,同时可以避免前面例子中所出现的歧义。
空格
空格的使用同样有助于改善代码的可读性和一致性。在写英文句子的时候,在逗号和句号后面会使用间隔,在JavaScript中,你可以按照同样的逻辑在表达式(相当于逗号)和语句结束(相对于完成了某个“想法”的表达)后面添加间隔。
适合使用空格的地方包括:
- for循环中的分号之后,比如
for (var i = 0; i < 10; i += 1) {...}
- for循环中初始化多个变量,比如
for (var i = 0, max = 10; i < max; i += 1) {...}
- 用于分隔数组元素的逗号之后,比如
var a = [1, 2, 3];
- 对象属性后的逗号以及名值对之间的冒号之后,比如
var o = {a: 1, b: 2};
- 函数参数中,比如
myFunc(a, b, c)
- 函数声明的花括号之前,比如
function myFunc() {}
- 匿名函数表达式
function
之后,比如var myFunc = function () {};
另外,我们推荐在运算符和操作数之间也添加空格。也就是说在+
、-
、*
、=
、<
、>
、<=
、>=
、===
、!==
、&&
、||
、+=
符号前后都添加空格。
// 适当且一致的空格给代码留了“呼吸空间”,使代码更易读
var d = 0,
a = b + 1;
if (a && b && c) {
d = a % c;
a += d;
}
// 反模式,缺少或者不正确的空格使得代码不易读
var d= 0,
a =b+1;
if (a&& b&&c) {
d=a %c;
a+= d;
}
最后,还应当注意,最好在花括号旁边添加空格:
- 在函数、
if-else
语句、循环、对象字面量的左花括号之前补充空格 - 在右花括号和
else
或者while
之间补充空格
垂直空白的使用经常被我们忽略,你可以使用空行来将代码单元分隔开,就像文学作品中使用段落进行分隔一样。