javascript 编码规范指南(6)

语句

简单语句
每一行最多只包含一条语句。所有简单的语句都应该以分号(;)结束。

返回语句
当返回一个值的时候不应当使用圆括号包裹。

复合语句,是大括号括起来的语句列表。
括起来的语句应当较复合语句多缩进一个层次。
开始的大括号应当在复合语句所在行的末尾;结束的大括号应当独占一行并且同复合语句的开始保持同样的缩进。
当语句是控制结构的一部分时,诸如 if 或者 for 语句,所有语句都需要用大括号括起来,也包括单个语句。这个约定使得我们更方便地添加语句而不用担心忘记加括号而引起bug。
像 if 一样的语句开始的关键词,其后应该紧跟一个空格,起始大括号应当在空格之后。

if 语句格式

if (condition) {
    statements
}

if (condition) {
    statements
} else {
    statements
}

if (condition) {
    statements
} else if (condition) {
    statements
} else {
    statements
}

绝不允许在if语句中省略花括号。

for 语句格式

for (initialization; condition; update) {
    statements
}

for (variable in object) {
    statements
}

for语句的初始化部分不应当有变量声明。

// Good
var i,
    len;
for (i=0, len=10; i < len; i++) {
    // code
}

// Bad: 初始化时声明变量
for (var i=0, len=10; i < len; i++) {
    // code
}

当使用 for-in 语句时,记得使用 hasOwnProperty() 进行双重检查来过滤出对象的成员。

while 语句格式

while (condition) {
    statements
}

do 语句格式

do {
    statements
} while (condition);

switch 语句格式

switch (expression) {
    case expression:
        statements

    default:
        statements
}

switch 下的每一个 case 都应当保持一个缩进。除第一个之外包括 default 在内的每一个case 都应当在之前保持一个空行。
每一组语句(除了 default) 都应当以 break 、return 、 throw 结尾,或者用一行注释表示跳过。

// Good
switch (value) {
    case 1:
        /* falls through */

    case 2:
        doSomething();
        break;
        
    case 3:
        return true;

    default:
        throw new Error("This shouldn't happen.);
}

如果一个switch 语句不包含 default 情况,应当用一行注释代替。

// Good
switch (value) {
    case 1:
        /*falls through*/
    
    case 2:
        doSomething();
        break;

    case 3:
        return true;

    // no default
}

try 语句格式

try {
    statements
} catch (variable) {
    statements
}

try {
    statements
} catch (variable) {
    statements
} finally
    statements
}

留白
在逻辑相关的代码块之间添加空行可以提高代码的可读性。

两行空格仅限在如下情况中使用:
在不同的源代码文件之间。
在类和接口定义之间。

单选空格仅限于在如下情况中使用:
方法之间;
方法中局部变量和第一行语句之间;
多行或者单行注释之前;
方法中逻辑代码块之间以提升代码的可读性。

空格应当在如下情况中使用:
关键词后跟括号的情况应当用空格隔开;
参数列表中括号之后应当保留一个空格;
所有的除了点(.)之上的二元去处符,其操作数都应当用空格隔开。单目运算符的操作数之间不应该用空白隔开,诸如一元头号,递增(++)、递减(--);
for语句中的表达式之间应当用空格隔开。

需要避免的
切勿使用像 String 一类的原始包装类型创建新的对象;
避免使用 eval() ;
避免使用 with 语句,该语句在严格模式中不复存在,可能在未来的ECMAScripts标准中也将去除。

javascript 编码规范指南(5)

严格模式
应当仅限在函数内部使用。

// Good
function doSomething() {
    "use strict";
    
    // code
}

如果期望多个函数中使用严格模式,可以使用立即被调用的函数。

// Good
(function() {
    "use strict";

    function doSomething() {
        // code
    }
    
    function doSomethingElse() {
       // code
    }

}());

赋值
当给变量赋值时,如果右侧是含有比较语句的表达式,需要用圆括号包裹。

// Good
var flag = (i < count);

// Bad: 遗漏圆括号
var flag = i < count;

等号运算符
使用=== (严格相等) 和 !== (严格不相等) 代替 == (相等) 和 != (不相等) 来避免弱类型转换错误。

// Good
var same = (a === b);

// Bad: Using ==
var same = (a == b);

三元操作符
三元运算符应当仅仅用在条件赋值语句中,而不要作为if语句的替代品。

// Good
var value = condition ? value1 : value2;

javascript 编码规范指南(4)

变量声明
变量应当在使用前定义,变量定义应当放在函数开头,使用一个var表达式每行一个变量。除了首行,所有行都应当多一层缩进以使变量名能够垂直方向对齐。初始化的变量应当在末初始化变量之前。

// Good
var count = 10,
    name = "Nicholas",
    found = false,
    empty;

// Bad: 多个定义写在一行
var count = 10, name = "Nicholas",
found = false, empty;

函数声明
函数应当在使用前定义,函数名和开始圆括号之间不应当有空格。结束的圆括号和右边的花括号之间应该留一个空格。右侧的花括号应当同function关键字保持同一行。
开始和结束括号之间不应该有空格。参数名之间应当在逗号之后保留一个空格。函数体应当保持一级缩进。

// Good
function doSomething(arg1, arg2) {
    return arg1 + arg2;
}

其他函数内部定义的函数应当在var语句后立即定义,先定义变量再定义函数。

// Good
function outer() {
    var count = 10,
    name = "Nicholas",
    found = false,
    empty;
    function inner() {
        // code
    }
    // code that uses inner()
}

匿名函数可能作为方法赋值给对象,或者作为其他函数的参数。function关键字同开始括号之间不应有空格。

// Good
object.method = function() {
    // code
};

// Bad:不正确的空格
object.method = function () {
    // code
};

立即被调用的函数应当在函数调用的外层用圆括号包裹。

// Good
var value = (function() {

    // 函数体

    return {
        message: "Hi"
    }
}());

// Bad: 函数调用外层没有用圆括号包裹
var value = function() {

    // function body

    return {
       message: "Hi"
    }
}();

命名规范
变量和函数命名应仅限于数字、字母、字符,某些情况下也可以使用下划线。

变量命名应当采用驼峰命名格式,首字母小写,接着每个单词首字母大写。变量名的第一个单词应当是一个名词(而非动词)。不要在变量命名中使用下划线。

// Good
var accountNumber = "8401-1";

// Bad: 大写字母开头
var AccountNumber = "8401-1";

// Bad: 动词开头
var getAccountNumber = "8401-1";

// Bad: 使用下划线
var account_number = "8401-1";

函数命名也应当采用驼峰命名格式。函数名的第一个单词应当是动词(而非名词),最好不使用下划线。

// Good
function doSomething() {
    // code
}

构造函数——通过new运算符创建新对象的函数——也应当以驼峰格式命名,并且首字符大写。构造函数名称应当以非动词开头,因为new代表着创建一个对象实例的操作。

// Good
function MyObject() {
    // code
}

常量(值不会被改变的变量)的命名应当是所有字母大写,不同单词之间用单个下划线隔开。

// Good
var TOTAL_COUNT = 10;

对象的属性同变量的命名规则相同。对象有方法同函数的命名规则相同。如果属性方法是私有的,应当在之前加一个下划线。

// Good
var object = {
    _count: 10,
    
    _getCount: function () {
       return this._count;
    }
};

javascript 编码规范指南(3)

注释
如下情况应当使用注释:
代码晦涩难懂。
可能被误认为错误的代码。
必须但并不明显的针对特定浏览器的代码。
对于对象、方法或者属性,生成文档是有必要的(使用恰当的文档注释)。

单行注释
用来说明一行代码或者一组相关的代码。单行注释以两个斜杠开始,行尾自动结束。注释前应添加一个空行,有三种使用方式:
独占一行的注释,用来解释下一行代码。
在代码行的尾部的注释,用来解释它之前的代码。
多行、用来注释掉一个代码块。

// Good
if (condition){

    // if you made it here, then all security checks passed
    allowed();
}

// Bad: 注释之前没有空行
if (condition){
    // if you made it here, then all security checks passed
    allowed();
}

对于代码行尾单行注释的情况,应确保代码结尾同注释之间至少一个缩进。

// Good
var result = something + somethingElse;    // somethingElse will never be null

// Bad: 代码和注释间没有缩进
var result = something + somethingElse;// somethingElse will never be null

注释一个代码块时在连续多行使用单行注释是唯一可以接受的情况。

多行注释
在代码需要更多文字去解释的时候使用。每个多行注释都至少有如下三行。
首行仅仅包括/*注释开始。不应该有其他文字。
接下来的行以*开头并保持左对齐。这些行可以有文字描述。
最后一行以*/开头并同先前行保持对齐。也不应该有其他文字。

多行注释的首行应当保持同它描述代码的相同层次的缩进,后续的每行应当有同样层次的缩进并附加一个空格(为了适当保持*字符的对齐)。每一个多行代码之前应当预留一个空行。

// Good
if (condition){

    /*
     * if you made it here,
     * then all security checks passed
     */
    allowed();
}

注释声明

TODO,说明代码还未完成。应当包含下一步要做的事情。
HACK,代码实现走了一个捷径。
XXX,说明代码是有问题的并应当尽快修复。
FIXME,同上,重要性略低于XXX
REVIEW,说明代码任何可能的改动都需要评审。

这些声明可能在一行或多行注释中使用,并且应当遵循同一般注释类型相同的格式规则。

javascript 编码规范指南(2)

运算符间距
二元运算符前后必须使用一个空格来保持表达式的整洁。操作符包括赋值运算符和逻辑运算符。

// Good
var found = (values[i] === item);

// Good
if (found && (count > 10)) {
    doSomething();
}

// Good
for (i = 0; i < count; i++) {
    process(i);
}

括号间距
当使用括号时,紧接左括号之后和紧接右括号之前不应该有空格。

// Good
var found = (values[i] === item);

// Good
if (found && (count > 10)) {
    doSomething();
}

// Good
for (i = 0; i < count; i++) {
    process(i);
}

对象直接量
起始左花括号应当同表达式保持同一行。
每个属性的名值对应当保持一个缩进,第一个属性应当在左花括号后另起一行。
每个属性的名值对应当使用不含引号的属性名,其后紧跟一个冒号(之前不含空格),而后是值。
倘若属性值是函数类型,函数体应当在属性名之下另起一行,而且其前后均应保留一个空行。
一组相关的属性前后可以插入空行以提升代码的可读性。
结束的右花括号应当独占一行。

// Good
var object = {
    key1: value1,
    key2: value2,
    func: function() {
        // do something
    },
    key3: value3
};

当对象字面量作为函数参数时,如果值是变量,起始花括号应当同函数名在同一行。

// Good
doSomething({
    key1: value1,
    key2: value2
});

// Bad: 所有代码在一行上
doSomething({ key1: value1, key2: value2 });

javascript 编码规范指南(1)

缩进
每一行的层级由4个空格组成,避免使用制表符(Tab)进行缩进。

// Good
if (true) {
    doSomething();
}

行的长度
每行长度不应该超过80个字符,如果一行多于80个字符,应当在一个运算符(逗号,加号等)后换行。下一行应当增加两级缩进(8个字符)。

// Good
doSomething(argument1, argument2, argument3, argument4,
        argument5);

原始值

1、字符串应当始终使用双引号(避免使用单引号)且保持一行。避免在字符串中使用斜线另起一行。

// Good
var name = "Nicholas";

// Bad: 字符串结束之前换行
var longString = "Here's the story, of a man \
named Brady.";

2、数字应当使用十进制整数,科学计数法表示整数,十六进制整数或者十进制浮点小数,小数点前后应当至少保留一位数字。避免使用八进制直接量。

// Good
var count = 10;
// Good
var price = 10.0;
var price = 10.00;
// Good
var num = 0xA2;
// Good
var num = 1e23;
// Bad: 十进制数字以小数点结尾
var price = 10.;
// Bad: 十进制数字以小数点开头
var price = .1;
// Bad: 八进制写法已废弃
var num = 010;

3、特殊值null除特殊情况下应当避免使用
用来初始化一个变量,这个变量可能被赋值为一个对象。
用来和一个已经初始化的变量比较,这个变量可以是也可以不是一个对象。
当函数的参数期望是对象时,被用作参数传入。
当函数的返回值期望是对象时,被用作返回值传出。

// Good
var person = null;

// Good
function getPerson() {
    if (condition) {
    return new Person("Nicholas");
    } else {
        return null;
    }
}

// Good
var person = getPerson();
    if (person !== null){
    doSomething();
}

// Bad: 和一个未被初始化的变量比较
var person;
if (person != null){
    doSomething();
}

4、避免使用特殊值 undefined。判断一个变量是否定义应当使用typeof操作符。

// Good
if (typeof variable == "undefined") {
    // do something
}

// Bad: 使用了undifined直接量
if (variable == undefined) {
    // do something
}