这是一篇翻译的文章,原文链接(http://javascript.crockford.com/code.html)
Javascript代码规范
这部分讲有关javascript的代码规范及规则。
软件的长期价值和它的代码质量是成正比的。在软件的声明周期中,代码可能会被很多人阅读和修改。如果程序具有良好的结构及特性,那么在修改过程会不那么容易崩溃,良好的代码规范可以增加程序的健壮性。
所有的javascript代码都直接呈现在公众的面前,我们需要注重它的质量和整洁性。
Javadcript文件
Javascript文件以.js命名
Javascrip代码不应该嵌入html代码中,除非是用于一次特定的会话,javascript代码加入到html中会增加文件的大小消耗资源,并且不能通过缓存和压缩的方式来减少消耗。
空行空格
在可能的情况下,这些规则与几个世纪的文学风格的良好实践是一致的。如果有强有力的证据表明有显着的好处,那么可以应该容忍与文学风格的偏差。
空行将代码断开为具有逻辑联系的代码段,来增加可读性。
空行的使用场景如下:
1)在关键字跟着左括号的情况下,关键字与左括号之间应该存在空格,这样可以很好的区分调用和那些非调用的情况,例如在if和while之后应在有空格
While (
2)调用函数时,函数名字和左括号之间不应该有空格。这样可以很好的区分开关键字和函数调用的情况
3)在一元运算符和操作数之间不应该存在空格,除非一元操作符是一个单词,例如typeof
4)每个二元运算符及其操作数应该通过一侧的空格隔开,除了句点(.)、左中括号([)、左括号(()
5)每个逗号之后应该是一个空格或者是一个空行
6)在程序语句中,分号后面应该跟着空行
7)在流程控制语句中,分号应该跟着一个空格
每个语句开始前应该缩进对齐,最外层代码应该和左边缘对其,每次缩进增长4个单位,如果上一行的最后一个字符是(、[、{等符号,那么它的闭合符号应该在新的一行的第一个字符位置。
由于三目运算表达式非常容易导致混淆,所以应该将问号(?)作为一行的开头,且缩进四个单位,对于冒号(:)应该重新开始一行,和上一行问号对齐。三目运算表达式的条件应该包含在括号中。
var integer = function (
value,
default_value
) {
value = resolve(value);
return (typeof value === "number")
? Math.floor(value)
: (typeof value === "string")
? value.charCodeAt(0)
: default_value;
};
如果句点(.)在一行的第一个位置,应该增加4个缩进。
避免一行语句太长,如果一条语句在一行之内看起来不是那么合适,应该把它断开为多行。在左大括号({)左中括号([)左括号(()之后的语句,或是在逗号(,)、句号(.)、问号(?)、冒号(:)之前的语句最好是断开。如果以上面方式断开时不可行的,那就在操作符之后断开,在下一行开始相对上一行开始增加8个缩进,那八个缩进不能影响正在递增进行的全局缩进。
这些子句(case, catch, default, else, finally)不是顺序语句,不应该像顺序语句那样缩进。
制表符和空格符不应该被混淆。我们应该选择其中一个符号来做分割使用,来避免两者混淆问题。个人偏好一个标准。无论是制表符还是空格都没有提供极大的优势,五年前制表符的优势在于消耗更少的内存空间,但是摩尔定律消除了这一优势,空格相对于制表符的优势在于更清晰,所以经常使用空格,你可以在编辑的时候使用制表符,但是在提交的时候需要确保它被替换成空格。可能会在某一天,我们会得到一个通用的标准,使更好的选择是空格。
注释
注释是很常用的,它让以后读代码的人更好的理解你的代码。应该认真的写注释,而且写得很清晰,应该像那些非常好的注释一样。偶尔可以有一些幽默感,但是不应该包含沮丧和抱怨。保持注释随代码修改而更新是很重要的。错误的注释会使程序更加难理解。
注释应该是有意义的,不应该为那些显而易见的代码加上注释,例如
i = 0; // Set i to zero.
不应该以此浪费读者的时间。
变量声明
所有变量在使用之前都应该被定义,虽然javascript并没有强制要求,但是在使用之前声明变量可以使变量更加的清楚,且更容易发现未被声明的隐藏变量。不应该使用隐含的全局变量,应该尽可能的减少全局变量的使用。
最好对每个变量进行声明和注释,并且尽可能按照字典的顺序排列。
var currentEntry; // currently selected table entry
var level; // indentation level
var size; // size of table
javascript变量没有块范围,所以在块中定义变量时可能会使那些对C相类似语言非常有经验的人产生混淆。
函数声明
所有都需要函数在使用之前被定义,内部函数应该遵循var语句形式。这样可以很清楚的看出函数内部包含哪些变量。函数名字和函数参数列表的左括号之间没有空格,函数参数列表的右括号和函数语句之前的大括号之间应该存在一个空格,函数内部语句应该缩进四个空格,函数的最后一个大括号应该和函数最开始声明处对齐。
function outer(c, d) {
var e = c * d;
function inner(a, b) {
return (e * a) + b;
}
return inner(0, 1);
}
这对于javascript来说是一个很好的约定,在javascript中函数和对象自变量可以出现在任何的地方,上述约定可以使复杂的javascript代码结构有很好的阅读性。
function getElementsByClassName(className) {
var results = [];
walkTheDOM(document.body, function (node) {
var array; // array of class names
var ncn = node.className; // the node's classname
// If the node has a class name, then split it into a list of simple names.
// If any of them match the requested name, then append the node to the list of results.
if (ncn && ncn.split(" ").indexOf(className) >= 0) {
results.push(node);
}
});
return results;
}
If a function literal is anonymous, there should be one space between the word function and the ( left parenthesis. If the space is omitted, then it can appear that the function's name is function, which is an incorrect reading.
div.onclick = function (e) {
return false;
};
that = {
method: function () {
return this.datum;
},
datum: 0
};
如果是匿名函数,在function和其后的左括号之间应该存在一个空格,如果空格被省略,那么函数的名字可能会被错认为是function,这是一个不正确的读法。
div.onclick = function (e) {
return false;
};
that = {
method: function () {
return this.datum;
},
datum: 0
};
应该尽量减少全局函数的使用,当一个函数要被立即调用时,整个调用表达式应该被包装在括号中,这样就可以清楚地看到产生的值是函数的结果,而不是函数本身。
var collection = (function () {
var keys = [];
var values = [];
return {
get: function (key) {
var at = keys.indexOf(key);
if (at >= 0) {
return values[at];
}
},
set: function (key, value) {
var at = keys.indexOf(key);
if (at < 0) {
at = keys.length;
}
keys[at] = key;
values[at] = value;
},
remove: function (key) {
var at = keys.indexOf(key);
if (at >= 0) {
keys.splice(at, 1);
values.splice(at, 1);
}
}
};
}());
Names
名字应该只由26个大写或者小写字母(A .. Z, a .. z),十个数字(0 .. 9)、以及下划线组成。尽量避免使用两个国家以上的字符,那样可能造成阅读和理解上的麻烦。在名字中不应该使用反斜杠和美元符号。在名字中,不要使用下划线作为第一个字符或者最后一个字符,下划线作为第一个和最后一个字符常用来表示私有的,但是在程序语言中并没有实际的语义。如果私有性是很重要的,应该尽量使用关闭,而不是使用缺少约束力的约定。大多数属性和函数值应该使用小写字母开始。必须和new一起使用的构造函数名字应该以大写字母开始。Javascript的new省略并不会在编译时和运行时产生警告和错误。但是会产生不好的事情,所以我们唯一能做的是用大写的形式约定。浏览器中的所有全局变量应该被大写。
语句
简单语句
每行最多包含一条语句,并以分号结束,函数或者对象字面量赋值语句也必须以分号结束。
JavaScript允许任何表达式成为语句。这很容易造成误解,特别是存在分号作为嵌入成分时。任何表达式应该被用作语句,例如赋值,调用,delete.
复合语句
1)混合语句是指被包含在花括号中的语句。嵌套的语句应该缩进更多的单位
2)左花括号应在复合语句开始行的末尾
3)右花括号应该重新开始一行,并与含有相对应的左花括号的行的开始对齐
4)在控制语句中,大括号应该用于所有语句,甚至是单个语句,这样可以很方便的增加新的语句,且不易引入错误。
标签
除了while、do、for、switch,其它语句是不允许被标记的。
返回
返回值必须和return关键字必须在同一行。
If语句
if语句应该是如下格式
if (condition) {
statements
}
if (condition) {
statements
} else {
statements
}
if (condition) {
statements
} else if (condition) {
statements
} else {
statements
}
For语句
for语句存在如下格式:
for (initialization; condition; update) {
statements
}
While语句
while (condition) {
statements
}
Do语句
do {
statements
} while (condition);
Switch语句
switch (expression) {
case expression:
statements
default:
statements
}
Try语句
try {
statements
} catch (variable) {
statements
}
try {
statements
} catch (variable) {
statements
} finally {
statements
}
Continue语句
尽量避免使用continue语句,它会导致控制语句的结构混乱
With语句
with语句应该避免使用
{} 和 []
使用{}代替new Object(),[]代替new Array()
当成员名是连续的整数时,使用数组,当成员名是字符串或者其他类型时使用对象
逗号
反对使用逗号
赋值表达式
在if和while条件部分反对赋值表达式
if (a = b) {
同时也应该避免
if (a == b) {
=== and !== Operators
应该尽量使用===和!==,避免使用==和!=
易混淆的加减号
不要在a+后面跟着+好,避免和++混淆,此处可以使用括号使表达式更清晰
total = subtotal + +myInput.value;可以更好的写成
total = subtotal + (+myInput.value);
eval是邪恶的
Eval是javascript最被滥用的特性,避免使用它。
eval有别的名字。 不要使用Function构造函数。 不要将字符串传递给setTimeout或setInterval。
f