JavaScript 代码规范

基本

  1. 变量在声明后才可以使用
  2. 多个变量同时声明,使用逗号( , )隔开,每个变量另起一行,最后一个变量后添加分号( ; )

    1
    2
    let foo,
    bar;
  3. 变量命名应当采用驼峰命名格式,普通变量的第一个单词应当是一个名词,函数名第一个单词应当是动词

    1
    2
    3
    4
    5
    let dialogShow = true;

    function search() {
    // do something
    }
  4. 初始化一个值尽量使用字面量

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    //good
    let str = '',
    obj = {},
    arr = [],
    bool = true;

    //bad
    let str = new String(),
    obj = new Object(),
    arr = new Array(),
    bool = new Boolean()
  5. 函数声明

    • 尽量使用声明式,因为这样函数会提升,保证在使用时就已经声明
    • 函数名和开始圆括号之间不应当有空格。
    • 结束的圆括号和右边的大括号之间应该留一个空格。
    • 右侧的大括号应当同function关键字保持同一行。
    • 开始和结束括号之间不应该有空格。
    • 参数名之间应当在逗号之后保留一个空格。
    • 函数体应当保持一级缩进。

      1
      2
      3
      function fn() {
      // do something
      }
  6. 多行对象声明

    • 起始左大括号应当同表达式保持同一行。
    • 每个属性的名值对应当保持一个缩进(两个空格),第一个属性应当在左大括号后另起一行。
    • 每个属性的名值对应当使用不含引号的属性名,其后紧跟一个冒号,而后插入一个空格,再加上值
    • 倘若属性值是函数类型,函数体应当在属性名之下另起一行
    • 结束的右大括号应当独占一行。
    • 对象作为函数参数时,起始大括号应当同函数名一行
      1
      2
      3
      4
      5
      6
      7
      let obj = {
      foo: 'foo',
      bar: 'bar',
      fn: function() {
      // do something
      },
      };
  7. 严格模式应当仅限于在函数内部使用 'use strict'

    1
    2
    3
    (function(){
    'use strict'
    })();
  8. 使用两个空格替代制表符的缩进,保证在不同编辑器有相同表现

  9. 运算符前后必须使用一个空格来保持表达式的整洁
  10. 当使用括号时,紧接左括号之后和紧接右括号之前不应该有空格

    1
    2
    3
    if (a & (b & c) > d) {
    // do something
    }
  11. 复合语句,使用大括号括起来的语句列表,比如iffor语句

    • 大括号之间的语句比外层多缩进一层
    • 开始的大括号应当在复合语句所在行的末尾;结尾的大括号独占一行,并与复合语句的开始保持对齐
    • 诸如iffor等控制结构的语句都需要用大括号括起来,即使仅有一条语句
      1
      2
      3
      for(let i = 0, len = arr.length; i < len; i++) {
      //do something
      }
  12. 使用 === 表示用于判断等于,使用 !== 用于判断不等

    1
    2
    3
    4
    5
    6
    7
    // good
    a === b;
    b !== c;

    // bad
    a == b;
    b != c;
  13. 三元操作符应当仅仅用在条件赋值语句中,不要作为if语句的替代品

    1
    2
    3
    4
    5
    // good
    let a = condition ? c : d;

    // bad
    let a = condition ? fn1() : fn2();
  14. 每一行一条语句,所有简单的语句都应该以分号(;)结束

  15. 避免使用 for...in 遍历数组,推荐使用 for(;;) 遍历数组
  16. 避免在非函数的代码块中声明函数函数
  17. 使用 try...catch 时尽量对捕获的异常进行处理

  18. 避免使用 eval,避免使用 with 语句

  19. 避免在原生数据类型扩展属性和方法

  20. 注释是对代码的说明,务必保证注释与代码的相关性

  21. 不可以在注释里写不必要的代码,直接删除
  22. 在注释之前尽量留白一行
  23. 使用独占一行的注释,来解释下一行代码
  24. 对于代码行尾的单行注释的情况,应确保代码结尾同注释符之间至少一个缩进
  25. 注释符和注释内容之间保持一个空格
  26. 多行注释使用/*...*/形式,避免使用多个//
  27. 多行注释符首行留空,每行*和注释内容之间保持一个空格
  28. 使用 /*...*/ 对方法的定义进行注解,可以适当添加入参(@param)、出参(@returns)等说明。更多说明标签请参考JSDoc

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    // good
    /*
    * 方法
    * @param {string} arg1 参数1
    * @param {string} arg2 参数2
    */
    function fn(arg1, arg2) {
    // do something
    }

    // bad
    // 方法
    function fn(arg1, arg2) {
    // do something
    }
  29. 尽量使用原生自带的属性和方法

    1
    2
    3
    4
    _.find(arr, item => {...});

    // good
    arr.find(item => {...});
  30. 尽量使用标准通用的属性和方法

    1
    2
    3
    4
    5
    // bad
    str[0];

    // good
    str.charAt(0)

es6

  1. 使用let替代var
  2. 常量使用const

  3. 静态字符串一律使用单引号或反引号,不使用双引号。动态字符串使用反引号。

  4. 尽量使用字符串模版进行字符串的拼接而不是加号,方便阅读和修改

    1
    2
    3
    4
    5
    // bad
    '字符串' + a + b + c;

    // good
    `字符串${a}${b}${c}`;
  5. 使用数组成员对变量赋值时,优先使用解构赋值。

    1
    2
    3
    4
    5
    6
    // bad
    let a = arr[0],
    b = arr[1];

    // good
    let [a, b] = arr;
  6. 函数的参数如果是对象,优先使用解构赋值。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    function fn(arg) {
    let a = arg.a,
    b = arg.b;
    }

    // good
    function fn({a, b}) {
    // do something
    }
  7. 如果函数返回多个值,优先使用对象的解构赋值,而不是数组的解构赋值。

  8. 单行定义的对象,最后一个成员不以逗号结尾。多行定义的对象,最后一个成员以逗号结尾

    1
    2
    3
    4
    5
    6
    7
    let obj = {
    foo: 'foo',
    bar: 'bar',
    fn: function() {
    // do something
    },
    };
  9. 对象尽量静态化,一旦定义,就不得随意添加新的属性。如果添加属性不可避免,要使用Object.assign方法。

  10. 浅拷贝数组使用(…),不要用Object.assign

    1
    2
    let source = { foo: "foo", bar: "bar" },
    target = {...source};
  11. 如果对象的属性名是动态的,可以在创造对象的时候,使用属性表达式定义。

  12. 对象的属性和方法,尽量采用简洁表达法,这样易于描述和书写

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    let foo = "foo",
    bar = "bar";

    let obj = {
    foo,
    bar,
    fn() {
    // do something
    },
    };
  13. 使用扩展运算符(…)拷贝数组

  14. 使用 Array.from 方法,将类类数组的对象转为数组。

  15. 立即执行函数可以写成箭头函数的形式。

  16. 需要使用函数表达式的场合,尽量用箭头函数代替。这样更简洁,而且绑定了 this

    1
    arr.map(item => {...});
  17. 箭头函数取代 .bind,不应再用 self/_this/that 绑定 this。

    1
    2
    3
    4
    5
    6
    7
    // bad
    arr.map(function (item) {
    // do something
    }.bind(arr));

    // good
    arr,map(item => {...});
  18. 简单的、单行的、不会复用的函数,建议采用箭头函数。如果函数体较为复杂,行数较多,还是应该采用传统的函数写法。

  19. 所有配置项都应该集中在一个对象,放在最后一个参数,布尔值不可以直接作为参数。
  20. 不要在函数体内使用 arguments 变量,使用 rest 运算符(…)代替。
  21. 使用默认值语法设置函数参数的默认值。

  22. 只有模拟现实世界的实体对象时,才使用 Object。如果只是需要 key: value 的数据结构,使用 Map 结构。

  23. 总是用 Class,取代需要 prototype 的操作。因为 Class 的写法更简洁,更易于理解。

  24. 使用extends实现继承,因为这样更简单,不会有破坏instanceof运算的危险。

  25. 首先,Module 语法是 JavaScript 模块的标准写法,坚持使用这种写法。使用import取代require

  26. 使用export取代module.exports
  27. 不要在模块输入中使用通配符(*)。

    1
    2
    3
    4
    5
    6
    7
    // bad
    import * as param from "./module";
    param.foo;
    param.bar;

    // good
    import { foo, bar } from "./module";
  28. 如果模块默认输出一个函数,函数名的首字母应该小写。

  29. 如果模块默认输出一个对象,对象名的首字母应该大写。