JavaScript 编码风格指南

写做本文旨在加深本身印象,也为了更多人的了解到JS编码风格,提升本身的编码质量 想了解更多的内容请阅读《编写可维护的JavaScript》html

缩进

  • 每一行的层级由4个空格组成,避免使用制表符 (Tab) 进行缩进
// 好的写法
if (true) {
    doSomething();
}
复制代码

行的长度

  • 每行长度不该超过80个字符。若是一行超过80个字符,应当在一个运算符 (逗号, 加号等) 后换行。下一行应当增长两级缩进(8个字符)
// 好的写法
doSomething(argument1, argument2, aegument3, argument4,
        argument5);
 
// 很差的写法:第二行只有4个空格的缩进
doSomething(argument1, argument2, aegument3, argument4,
    argument5);

// 很差的写法:在运算符以前换行
doSomething(argument1, argument2, aegument3, argument4
        , argument5);
复制代码

原始值

  • 字符串应当始终使用双引号 (避免使用单引号) 且保持一行,避免在字符串中使用斜线另起一行 我的建议: html 用双引号, js 用单引号; 反之, 亦可
// 好的写法
var name = "Nicholas";

// 很差的写法: 单引号
var name = 'Nicholas';

// 很差的写法: 字符串结束以前换行
var longString = "Here's the story, of a man \ named Brady.";
复制代码
  • 数字应当使用十进制整数,科学计算法表示整数,十六进制整数,或者十进制浮点小数,小数先后应当至少保留一位数字。避免使用八进制直接量
// 好的写法
var count = 10;

// 好的写法
var price = 10.0;
var price = 10.00;

// 好的写法
var num = 0xA2;

// 好的写法
var num = 1e23;

// 很差的写法: 十进制数字以小数点结尾
var price = 10.;

// 很差的写法: 十进制数字以小数点开头
var price = .1;

// 很差的写法: 八进制 (base 8) 写法已废弃
var num = 010;
复制代码
  • 特殊值null除了下述状况下应当避免使用
    • 用来初始化一个变量,这个变量可能被赋值为一个对象
    • 用来和一个已经初始化的变量比较,这个变量能够是也能够不是一个对象
    • 当函数的参数指望是对象时,被用做参数传入
    • 当函数的返回值指望是对象时,被用做返回值传出
// 好的写法
var person = null;

// 好的写法
function getPerson() {
    if (condition) {
        return new Person("Nicholas");
    } else {
        return null;
    }
}

// 好的写法
var person = getPerson();
if (person != null) {
    doSomething();
}

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

// 很差的写法: 经过测试判断某个参数是否传递
function doSomething(arg1, arg2, arg3, arg4) {
    if (arg4 != null) {
        doSomethingElse();
    }
}
复制代码
  • 避免使用特殊值 undefined。判断一个变量是否认义应当使用 typeof 操做符
// 好的写法
if (typeof variable == "undefined") {
    // do something
}
 
// 很差的写法: 使用了 undefined 直接量
if (variable == undefined) {
    // do something
}
复制代码

运算符间距

  • 二元运算符先后必须使用一个空格来保持表达式的整洁。操做符包括赋值运算符和逻辑运算符
// 好的写法
var found = (values[i] === item);

// 好的写法
if (found && (count > 10)) {
    doSomething();
}
 
// 好的写法
for (i = 0; i < count; i++) {
    process(i);
}

// 很差的写法: 丢失了空格
var found = (values[i]===item);
 
// 很差的写法: 丢失了空格
if (found&&(count>10)) {
    doSomething();
}

// 很差的写法: 丢失了空格
for (i=0; i<count; i++) {
    process(i);
}
复制代码

括号间距

  • 当使用括号时,紧接左括号以后和紧接右括号以前不该该有空格
// 好的写法
var found = (values[i] === item);
 
// 好的写法
if (found && (count > 10)) {
    doSomething();
}
 
// 好的写法
for (i = 0; i < count; i++) {
    process(i);
}

// 很差的写法: 左括号以后有额外的空格
var found = ( values[i] === item);

// 很差的写法: 右括号以前有额外的空格
if (found && (count > 10) ) {
    doSomething();
}

// 很差的写法: 参数两边有额外的空格
for (i = 0; i < count; i++) {
    process( i );
}
复制代码

对象直接量

  • 对象直接量应当有以下格式
    • 起始左花括号应当同表达式保持同一行
    • 每一个属性的名值对应当保持一个缩进,第一个属性应当在左花括号后另起一行
    • 每一个属性的名值对应当使用不含引号的属性名,其后紧跟一个冒号(以前不含空格),然后是值
    • 假若属性值是函数类型,函数体应当在属性名之下另起一行,并且其先后均应保留一个空行
    • 一组相关的属性先后能够插入空行以提高代码的可读性
    • 结束的右花括号应当独占一行
// 好的写法
var object = {
 
    key1: value1,
    key2: value2,
 
    func: function() {
        // doSomething
    },
 
    key3: value3
};
 
// 很差的写法:不恰当的缩进
var object = {
                key1: value1,
                key2: value2
          };
 
// 很差的写法:函数体周围缺乏空行
var object = {
 
    key1: value1,
    key2: value2,
    func: function() {
        // doSomething
    },
    key3: value3
};
复制代码
  • 当对象字面量做为函数参数时,若是值是变量,起始花括号应当同函数名在同一行。全部其他先前列出的规则一样适用
// 好的写法
doSomething({
    key1: value1,
    key2: value2
});

// 很差的写法:全部代码在一行上
doSomething({ key1: value1, key2: value2 });

复制代码

注释

  • 频繁地使用注释有助于他人理解你的代码。以下状况应当使用注释
    • 代码晦涩难懂
    • 可能被误认为错误的代码
    • 必要但不明显的针对特定浏览器的代码
    • 对于对象、方法或者属性,生成文档是有必要的(使用恰当的文档注释)

单行注释

  • 单行注释应当用来讲明一行代码或者一组相关的代码。单行注释可能有三种使用方式
    • 独占一行的注释,用来解释下一行代码
    • 在代码行的尾部的注释,用来解释它以前的代码
    • 多行,用来注释掉一个代码块
// 好的写法
if (condition) {
 
    // 若是代码执行到这里,则代表经过了全部安全性检查
    allowed();
}
 
// 很差的写法:注释以前没有空行
if (condition) {
    // 若是代码执行到这里,则代表经过了全部安全性检查
    allowed();
}
 
// 很差的写法:错误的缩进
if (condition) {
 
// 若是代码执行到这里,则代表经过了全部安全性检查
    allowed();
}

// 很差的写法:这里应当使用多行注释
// 接下来的这段代码很是难,那么,让我详细的解释一下
// 这段代码的做用氏首先判断条件是否为真
// 只有为真时才会执行。这里的条件是经过
// 多个函数计算出来的,在整个会话生命周期内
// 这个值氏能够被修改的
if (condition) {
    // 若是代码执行到这里,则代表经过了全部安全检查
    allowed();
}
复制代码
  • 对于代码行尾单行注释的状况,应确保代码结尾同注释之间至少一个缩进
// 好的写法
var result = something + somethingElse; // somethingElse will never be null
 
// 很差的写法: 代码和注释间没有足够的空格
var result = something + somethingElse;// somethingElse will never be null
复制代码
  • 注释一个代码块时在连续多行使用单行注释是惟一能够接受的状况.。多行注释不该当在这种状况下使用
// 好的写法
// if (condition) {
//     doSomething();
// }
复制代码

多行注释

  • 多行注释应当在代码须要更多文字去解释的时候使用。每一个多行注释都至少有以下三行
    • 首行仅仅包括/*注释开始。该行不该当有其余文字
    • 接下来的行以*开头并保持左对齐。这些能够有文字描述
    • 最后一行以*/开头并同先前行保持对齐。也不该有其余文字
  • 多行注释的首行应当保持同它描述代码的相同层次的缩进。后续的每行应当有一样层次的缩进并附加一个空格(为了适当保持*字符的对齐)。每个多行代码以前应当预留一个空行
// 好的写法
if (condition) {
 
    /*
     * 若是代码执行到这里
     * 说明经过了全部的安全检测
     */
    allowed();
}

// 很差的写法: 注释以前无空行
if (condition) {
    /*
     * 若是代码执行到这里
     * 说明经过了全部的安全检测
     */
    allowed();
}

// 很差的写法: 星号后没有空格
if (condition) {
 
    /*
     *若是代码执行到这里
     *说明经过了全部的安全检测
     */
    allowed();
}

// 很差的写法: 错误的缩进
if (condition) {
 
/*
 * 若是代码执行到这里
 * 说明经过了全部的安全性检测
 */
    allowed();
}
 
// 很差的写法: 代码尾部注释不要用多行注释格式
var result = something + somethingElse; /*somethingElse 不该当取值为null*/
复制代码

声明

注释声明

  • 注释有时候也能够用来给一段代码声明额外的信息。这些声明的格式以单个单词打头并紧跟一个冒号。可使用的声明以下
    • TODO
      • 说明代码还未完成。应当包含下一步要作的事情
    • HACK
      • 代表代码实现走了一个捷径。应当包含为什么使用 hack 的缘由。这也可能代表该问题可能会有更好的解决办法
    • XXX
      • 说明代码是有问题的并应当尽快修复
    • FIXME
      • 说明代码是有问题的并应尽快修复。重要性略次于XXX
    • REVIEW
      • 说明代码在任何可能的改动都须要评审
  • 这些声明可能在一行或者多行注释中使用,而且应当遵循同通常注释类型相同的格式规则
// 好的写法
// TODO: 我但愿找到一种更快的方式
doSomething();

// 好的写法
/*
 * HACK: 不得不针对 IE 作的特殊处理. 我计划后续有时间时
 * 重写这部分. 这些代买可能须要在 v1.2 版本以前替换掉
 */
if (document.all) {
    doSomething();
}

// 好的写法
// REVIEW: 有更好的方法吗?
if (document.all) {
    doSomething();
}

// 很差的写法: 注释声明空格不正确
// TODO :  我但愿找到一种更快的方式
doSomething();
 
// 很差的写法: 代码和注释应当保持一样的缩进
    // REVIEW: 有更好的方法吗?
if (document.all) {
    doSomething();
}
复制代码

变量声明

  • 全部的变量在使用前都应当事先定义。变量定义应当放在函数开头,使用一个 var 表达式每行一个变量。除了首行,全部行都应当多一层缩进以使变量名可以垂直方向对齐。变量定义时应当初始化,而且赋值操做符应当爆出一致的缩进。初始化的变量应当在未初始化变量以前
// 好的写法
var count = 10,
      name = "Nicholas",
      found = false,
      empty;

// 很差的写法: 不恰当的初始化赋值
var count = 10,
     name = "Nicholas",
     found= false,
     empty;

// 很差的写法: 错误的缩进
var count = 10,
name = "Nicholas",
found = false,
empty;

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

// 很差的写法: 未初始化的变量放在最前面
var empty,
      count = 10,
      name = "Nicholas",
      found = false;

// 很差的写法: 多个 var 表达式
var count = 10,
      name = "Nicholas";

var found = false,
      empty;
复制代码

函数声明

  • 函数应当在使用前提早定义。一个不是做为方法的函数(也就是说没有做为一个对象的属性)应当使用函数定义的格式(不是函数表达式和 Function 构造器格式)。函数名和开始圆括号之间不该当有空格。结束的圆括号和右边的花括号之间应该留一个空格。右侧的花括号应当同 function 关键字保持同一行。开始和结束括号之间不该该有空格。参数名之间应当在都好以后保留一个空格。函数体应当保持一级缩进。
// 好的写法
function doSomething(arg1, arg2) {
    return arg1 + arg2;
}

// 很差的写法: 第一行不恰当的空格
function doSomething (arg1, arg2) {
    return arg1 + arg2;
}

// 很差的写法: 函数表达式
var doSomething = function doSomething(arg1, arg2) {
    return arg1 + arg2;
}

// 很差的写法: 左侧的花括号位置不对
function doSomething(arg1, arg2) 
{
    return arg1 + arg2;
}

// 错误的写法: 使用了 Function 构造器
var doSomething = new Function("arg1", "arg2", "return arg1 + arg2")
复制代码
  • 其余函数内部定义的函数应当在 var 语句后当即定义
// 好的写法
function outer() {
    
    var count = 10,
        name = "Nicholas",
        found = false,
        empty;

    function inner() {
        // 代码
    }

    // 调用 inner() 的代码
}

// 很差的写法: inner 函数的定义先于变量
function outer() {
    
    function inner() {
        // 代码
    }
    
    var count = 10,
        name = "Nicholas",
        found = false,
        empty;

    // 调用 inner() 的代码
}
复制代码
  • 匿名函数可能做为方法赋值给对象,或者做为其余函数的参数。function 关键字同开始括号之间不该有空格
// 好的写法
object.method = function() {
    // 代码
};

// 很差的写法: 不正确的空格
object.method = function () {
    // 代码
};
复制代码
  • 当即被调用的函数应当在行数调用的外层用圆括号包裹
// 好的写法
var value = (function() {
    
    // 函数体

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

// 很差的写法: 函数调用外层没有用圆括号包裹
var value = function() {
    
    // 函数体

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

// 很差的写法: 圆括号位置不当
var value = (function() {
    
    // 函数体

    return {
        message: "Hi"
    }
})();
复制代码

赋值

  • 给变量赋值时,若是右侧是含有比较语句的表达式,须要用圆括号包裹
// 好的写法
var flag = (i < count);
 
// 很差的写法:遗漏圆括号
var flag = i < count;
复制代码

命名

  • 变量和函数在命名时应当当心。命名应仅限于数字字母字符,某些状况下可使用下划线。最好不要在任何命名中使用美圆符号($)或者反斜杠(\)
  • 变量命名应当采用驼峰命名格式,首字母小写,每一个单词首字母大写。变量名的第一个单词应当是一个名词 (而非动词) 以免同函数混淆。不要在变量名中使用下划线
// 好的写法
var accountNumber = "2312";
  
// 很差的写法:大写字母开头
var AccountNumber = "2312";
 
// 很差的写法:动词开头
var getAccountNumber = "2312";
 
// 很差的写法:使用下划线
var account_number = "2312";
复制代码
  • 函数名也应当采用驼峰命名格式。函数名的第一个单词应当是动词(而非名词)来避免同变量混淆。函数名中最好不要使用下划线
// 好的写法
function doSomething() {
    // 代码
}
 
// 很差的写法:大写字母开头
function DoSomething() {
    // 代码
}
 
// 很差的写法:名词开头
function something() {
    // 代码
}
 
// 很差的写法:使用下划线
function do_something() {
    // 代码
}
复制代码
  • 这里有一些使用动词常见的约定
动词 含义
can 函数返回一个布尔值
has 函数返回一个布尔值
is 函数返回一个布尔值
get 函数返回一个非布尔值
set 函数用来保存一个值
if (isEnabled()) {
    setName("Nicholas");
}

if (getName() === "Nicholas") {
    doSomething();
}
复制代码
  • 构造函数——经过new运算符建立新对象的函数——也应当以驼峰格式命名而且首字符大写。构造函数名称应当以非动词开头,由于new表明着建立一个对象实例的操做
// 好的写法
function MyObject() {
    // 代码
}

// 很差的写法:小写字母开头
function myObject() {
    // 代码
}

// 很差的写法:使用下划线
function my_object() {
    // 代码
}

// 很差的写法:动词开头
function getMyObject() {
    // 代码
}
复制代码
  • 常量(值不会被改变的变量)的命名应当是全部大写字母,不一样单词之间单个下划线隔开
// 好的写法
var TOTAL_COUNT = 10;
 
// 很差的写法:驼峰形式
var totalCount = 10;
 
// 很差的写法:混合形式
var total_COUNT = 10;
复制代码
  • 对象的属性同变量的命名规则相同。对象的方法同函数的命名规则相同。若是属性或者方法是私有的,应当在以前加上一个下划线
// 好的写法
var object = {
    _count: 10,

    _getCount: function() {
        return this._count;
    }
}
复制代码

严格模式

  • 严格模式应当仅限在函数内部使用,千万不要在全局使用
// 很差的写法:全局使用严格模式
"use strict";
 
function doSomething() {
    // 代码
}
  
// 好的写法
function doSomething() {
    "use strict";

    // 代码
}
复制代码
  • 若是你指望在多个函数中使用严格模式而不须要屡次声明“use strict”,可使用当即被调用的函数
// 好的写法
(function() {
    "use strict";

    function doSomething() {
        // 代码
    }

    function doSomethingElse() {
        // 代码
    }
}());
复制代码

运算符

等号运算符

  • 使用===(严格相等)和!==(严格不相等)代替==(相等)和!=(不等)来避免弱类型转换错误
// 好的写法
var same = (a === b);
 
// 好的写法
var same = (a == b);
复制代码

三元运算符

  • 三元运算符应当仅仅用在条件赋值语句中,而不要做为if语句的替代品
// 好的写法
var value = condition ? value1 : value2;
 
// 很差的写法: 没有赋值, 应当使用 if 表达式
condition ? doSomething() : doSomethingElse;
复制代码

语句

简单语句

  • 每一行最多只包含一条语句。全部简单的语句都应该以分号(;)结束
// 好的写法
count++;
a = b;
 
// 很差的写法:多个表达式写在一行
count++; a = b;
复制代码
  • 返回语句
    • 返回语句当返回一个值的时候不该当使用圆括号包裹,除非在某些状况下这么作可让返回值更容易理解。例如
return;
 
return collection.size();
 
return (size > 0 ? size : defaultSize);
复制代码

复合语句

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

if 语句

  • if 语句应当是下面的格式
if (condition) {
    statements
}
 
if (condition) {
    statements
} else {
    statements
}
 
if (condition) {
    statements
} else if (condition) {
    statements
} else {
    statements
}
复制代码
  • 毫不容许在if语句中省略花括号
// 好的写法
if (condition) {
    doSomething();
}
 
// 很差的写法:不恰当的空格
if (condition){
    doSomething();
}

// 很差的写法: 遗漏花括号
if (condition)
    doSomething(); 

// 很差的写法:全部代码都在一行
if (condition) { doSomething(); }
 
// 很差的写法:全部代码都在一行且没有花括号
if (condition) doSomething();
复制代码

for 语句

  • for 类型的语句应当是下面的格式
for (initialization; condition; update) {
    statements
}

for (variable in object) {
    statements
}
复制代码
  • for语句的初始化部分不该当有变量声明
// 好的方法
var i,
    len;
 
for (i=0, len=0; i < len; i++) {
    // 代码
}
 
// 很差的写法:初始化时候声明变量
for (var i=0, len=0; i < len; i++) {
    // 代码
}
 
// 很差的写法:初始化时候声明变量
for (var prop in object) {
    // 代码
}
复制代码
  • 当使用for-in语句时,记得使用hasOwnProperty()进行双重检查来过滤对象的成员

while 语句

  • while 类的语句应当是下面的格式
while (condition) {
    statements
}
复制代码

do 语句

  • do 类的语句应当是下面的格式
do {
    statements
} while (condition);
复制代码

switch 语句

  • switch 类的语句应当是以下格式
switch (expression) {
    case expression:
        statements
 
    default:
        statements
}
复制代码
  • switch 下的第一个 case 都应当保持一个缩进。除第一个以外包括 default 在内的每个 case 都应当在以前保持一个空行
  • 每一组语句(除了default)都应当以 break、return、throw 结尾,或者用一行注释表示跳过
// 好的写法
switch (value) {
    case 1:
        /* falls through */
 
    case 2:
        doSomething();
        break;
 
    case 3:
        return true;
 
    default:
        throw new Error("Some error");
}
复制代码
  • 若是一个switch语句不包含default状况,应当用一行注释代替
// 好的写法
switch (value) {
  case 1:
    /* falls through */
 
  case 2:
    doSomething();
    break;
 
  case 3:
    return true;
 
  default:
    // 没有default
}
复制代码

try 语句

  • try类的语句应当格式以下
try {
    statements
} catch (variable) {
    statements
}

try {
    statements
} catch (variable) {
    statements
} finally {
    statements
}
复制代码

留白

  • 在逻辑相关的代码之间添加空行代码能够提升代码的可读性
  • 两行空行仅限于在以下状况下使用
    • 在不一样的源代码文件之间
    • 在类和接口定义之间
  • 单行空行仅限在以下状况中使用
    • 方法之间
    • 方法中局部变量和第一行语句之间
    • 多行或者单行注释以前
    • 方法中逻辑代码块之间以提高代码的可读性
  • 空格应当在以下的状况下使用
    • 关键词后跟括号的状况应当用空格隔开
    • 参数列表中逗号以后应当保留一个空格
    • 全部的除了点(.)以外的二元运算符,其操做数都应当用空格隔开。单目运算符的操做数之间不该该用空白隔开,例如一元减号,递增(++),递减(--)
    • for 语句的表达式之间应当用空格隔开

注意

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

最后

  • 上述指南并非在开发过程当中必须彻底遵照的 (好比说引号和缩进等),咱们能够只汲取其中的一部分来改善本身的编码风格,让本身的代码易读、可维护。关于编码风格,每一个团队都有本身的特点,只要保持团队一致性,能够高效的开发就OK了
相关文章
相关标签/搜索