第一部分 编程风格
每个人都有自己独特的编程风格,有情有独钟亦或恨之入骨的,每个人都希望用自己的方式制定规范来实施。这些应当被归为个人编程嗜好。我们需要的是在编程过程中尽早的确定统一的编程风格。
在团队开发中,编程风格一致性变得尤为重要,因为:
1 任何开发者都不在乎某个文件的作者是谁,也没有必要花费额外的精力去理解代码的逻辑并且重新排版,因为所有代码的排版风格都是非常一致的,因为风格不一致会导致我们打开代码文件的第一件事情不是立即工作,而是进行缩进的排版整理。
2 能很容易的辨别出有问题的代码并且发现错误,如果所有的代码风格很像,当看到一段与众不同的代码时,很肯能问题就出在这里。
JSLint 和 JSHint 是两个检查编程风格的工作。不仅找出代码中潜在的错误,还能对潜在的风格问题给予提示警告。
“程序是写给人读的,只是偶尔让计算机执行一下” - Donald Knuth
第一章 基本的格式化
编程风格的核心就是基本的格式化规范,这些规范决定着如何编写高水准的代码。
1.1 缩进层级
所有语言都是如此,都会讨论如何对代码缩进。
if(wl && wl.length){
for(var i=0; i
p = wl[i];
type=Y.Lang.type(wl[i]);
...
}
}
稍微编写过程序的都不会使用上面的格式,害人害己。
if(wl && wl.length){
for(var i=0; i
p = wl[i];
type=Y.Lang.type(wl[i]);
...
}
}
代码应该如何统一缩进其实一直没有统一的共识。1.使用制表符缩进 。 2.使用空格缩进。
jQuery 明确规定使用制表符缩进。
Dauglas Crockford 的 JavaScript 规定使用4个空格缩进。
Google 的 JavaScript规定使用2个空格缩进。
Dojo 编程风格指南使用制表符缩进。
尼古拉斯(作者)建议4个空格,或在编辑器中设置一个 制表符 替换为 4个空格。为一个缩进层。
1.2 语句结尾
强制规定,语句结束插入分号。
function(){
return
{
...
}
}
上面代码就会引起问题。
1.3 行的长度
很少有JS的规范提及到行的长度的风格的,很多语言都建议行的字数不超过 80 字,因为很早以前的编辑器,这是最大的行长度。
Java语言规范中 源码单行长不超过 70 字,文档中单行长不超过 80 字。
Android开发者规范中规定不超过 100 字。
非官方的Ruby规定不操过 80 字。
Python编程规范规定单行不超过 79 字。
JavaScript 在 Crockford 代码规范中规定为 80 字符。
1.4 换行
当一行字字符数超过了最大限制的时候就需要换行。通常会在运算符之后换行,下一行会增加2个层级的缩进。
callFunction(document,"aaaaaaaaaaaaaaa","bbbbbbbbbbbbbbbb","cccccccccccccccccccc",
"bbbbbbbbbbbbbbbbbbb");//超出首字母c的2个层级
需要注意的是规范为在运算符之后换行,以及增加2个层级的缩进。
当然如果是赋值的话就保持赋值运算符对其。
var result = "aaaaaaaaaaaaaaaa" + "bbbbbbbbbbbbbbbb" + "ccccccccccccccccccc" +
"ddddddddddddddddddddddddd";
1.5 空行
空行常常被忽略,但是空行也是提高代码可读性的强大武器。
if(wl && wl.length){
for(var i=0; i
p = wl[i];
type=Y.Lang.type(wl[i]);
if(a){
...
}
}
}
空行一般来说不是很好在规范中规定,
1.方法之间
2.方法中局部变量可第一条语句之间。
3.多行或者单行注释之前。
4.在方法内的逻辑片段之前。
目前没有规范对空行进行明确的规定。
1.6 命名
"计算机科学只存在两个难题:缓存失效和命名" - Phil Karlton
只要写代码就会涉及到变量和函数,所以变量和函数的命名对于增强代码的可读性至关重要。
JavaScripe 遵循 ECMA ,即驼峰式大小写。
var myName;
var anotherName;
google Dojo等规范都规定使用小驼峰命名法。,当然还有一种曾经风光一时的 匈牙利命名法。
1.6.1 变量和函数
变量名总是应该遵循驼峰大小写命名法,并且命名的前缀应当是名词,使得可以将变量和函数区分开。
// 以下OK
var count = 10;
var myName = "Ni";
var found = true;
// 以下就需要重新命名
var getCount = 10;
var isFound = true;
//函数应当以动词开头
var getName = function(){
return myName;
};
还有一点示范
can 函数返回布尔值
has 函数返回布尔值
is 函数返回布尔值
get 函数返回非布尔值
set 函数用来保存值
1.6.2 常量
JS中没有常量的概念。来自C语言的约定,常量使用大写字母并且使用下划线命名。
var MAX_COUNT = 10;
var URL = "";
google Dojo 等编程风格指南都规定如此。
1.6.3 构造函数
JS中的构造函数只不过是冠以 new 运算符的函数而已。采用大驼峰命名法。
function Person( name ){
this.name = name;
}
1.7 直接量
JS中的原始值:字符串、数字、布尔值、null和underfined。
1.7.1 字符串
JS中的字符串使用双引号和单引号是完全相同的。对于规范只需要统一即可。
jQuery 和 Crockford规范为双引号来括住字符串,google规范为单引号括住字符串。
1.7.2 数字
JS中整数和浮点数都存储为相同的数据类型。
不推荐使用 10. 和 .1 的写法。会产生歧义,是否是我们漏掉了数字。
1.7.3 null
null 常会与 undefined 搞混淆。以下场景才应当使用null:
1. 用来初始化变量,该变量可能被赋值为对象。
2. 用来和一个已经初始化的变量进行比较,这个变量可以是非对象。
3. 当函数期望的参数是对象,用作参数传入。
4. 当函数的返回值期望是对象时,用作返回值传出。
以下场景不应当使用 null:
1. 不要使用null来检测是否传入了参数。
2. 不要用null来检测一个未初始化的变量。
var person = null;
function getPerson(){
if( condition ){
return new Person("ABC");
}else{
return null;
}
}
对于 null 的理解最好是当做对象的占位符使用,主流的规范没有提及。
1.7.4 undefined
由于
var person;
typeof person; // undefined
typeof foo; // undefined
以及
null == undefined
所以,禁止使用特殊值 undefined 可以有效地确保只在一种情况下 typeof 才返回 undefined。
1.7.5 对象直接量 与 数组直接量(字面量)
创建对象与数组最流行的方法为对象字面量和数组字面量,比相应的构造函数式创建更高效直接。
第二章 注释
2.1 单行注释
三种使用方法:
1. 独占一行,用来解释下一行,并且这行注释之前总有一行空行,缩进的层级与下一行代码保持一致。
2.在代码行的尾部注释。代码与注释之间至少有一个缩进。注释包括之前本行的代码不应该超过最大字符数限制。
3.注释掉大块代码。
// 好的注释方法
if( condition ){
// 解释下一行代码
func();
}
// 不好的注释方法
if( condition ){
// 解释下一行代码
func();
}
if( condition ){
// 解释下一行代码
func();
}
2.2 多行注释
偏向使用 Java 风格的注释
/*
* 这里是注释
* 这里是注释
* 这里是注释
*/
缩进的格式与单行注释表示一致。
2.3 使用注释
当代码不够清晰的时候使用注释,当代码很明了的时候不应当添加注释。
并且注释不应该只是解释变量名称或者函数名称式的那种废话。
当代码很难理解或者代码可能被误认为错误的代码的时候,需要添加注释。
2.4 文档注释
技术角度来说,文档注释并不是 JS 的组成部分,但是是一种普遍的实践。
1.应当对所有的方法和可能的返回值添加描述。
2.对自定义的构造函数类型和期望的参数添加描述。
3.对于包含对象或者方法的对象进行描述。
第三章 语句和表达式
JS中,诸如 if 和 for 之类的规定不管是单行代码还是多行代码,均使用 { }
// 好的写法
if( contidion ){
foo();
}
if( conidion ){
foo();
foo();
}
// 不好的写法
if( contidion ){ foo(); }
if( contidion ) foo();
所有的语句块都应当使用 { }, if , for , while ,do while , try catch finnally 。
3.1 花括号对齐方式
有两种对齐方式
if( conidion ){
foo();
foo();
}
和
if( conidion )
{
foo();
foo();
}
很显然由于第二种又时候会会让浏览器执行代码的时候产生不一样的解析,所以使用第一种花括号对齐方式。
3.2 块语句间隔
语句块间隔有3中形式:
1.语句名 圆括号 左花括号间没有空格间隔。
2.左圆括号之前 右圆括号之后添加一个空格。
3.左圆括号 右圆括号前后都添加一个空格。
作者推荐一致使用第二种形式。
3.3 switch 语句
JS中任何表达式都可以合法的用于case从句中,其他语言必须使用原始值和常量。
3.3.1 缩进
JS的switch缩进一致是有争议的话题。
switch (condition) {
case "a":
//代码
break;
case "b":
//代码
break;
default :
// 代码
}
每个case相对于switch都有一个缩进层。
第二个case开始之前都有一个空行。
另一种 Crockford 和Dojo编程风格为
switch (condition) {
case "a":
//代码
break;
case "b":
//代码
break;
default :
// 代码
}
3.3.2 case语句的连续执行(贯穿)
switch (condition) {
case "a":
case "b":
//代码
break;
default :
// 代码
}
Douglas 在 Crockford中禁止出现贯穿现象, 但是Nichlas认为只要程序逻辑很清楚,贯穿完全是一个可以接受的编程方式。Jquery 编程风格中也是允许的。
3.3.3 default
是否在任何时候都需要 default。
switch (condition) {
case "a":
case "b":
//代码
break;
//没有 default :
}
更倾向于没有默认行为并且在注释中写入省略 default。
3.4 with
with 语句可以更改包含上下文解析变量的方式。通过with可以使用局部变量的方式和函数的形式来访问特定对象中的属性和方法。可以缩短代码的长度。
但是是的JS引擎与压缩工具无法压缩。严格模式中 with 是禁止的。 基本所有的规范中都禁止使用 with。
3.5 for 循环
对于for循环中的 break 和 return 会改变循环的方向,尽量避免使用,但是不禁止。
3.6 for-in 循环
for-in循环建议与 hasOwnProperty 一起检测属性,除非你需要检查原型。
for-in是用来遍历对象的,不要用其来遍历数组。