编写可维护的 JavaScript

优质
小牛编辑
135浏览
2023-12-01

这是出版于2013年的书。编写可维护的JavaScript的重要性不言而喻,特别对于团队工作来讲。统一规范的编码规范、严谨的编码风格,能在代码的维护时节约大量的人力成本。

基本的格式化

  • 缩进层级:缩进层级到底采用制表符(tab)/2个空格/4个空格,都不重要,重要的是在一个团队中约定一种缩进风格。无关优劣,在这里风格统一最重要。另一个重要的点就是,切忌制表符和空格混用
  • 语句结尾:是否要分号结尾。虽然JS分析器有自动分号插入机制(ASI),但添加分号依然是广为推崇的编码风格。

      function foo() {
          return
              {
                  name: 'laoli'
              }
      }
    
      /*上面的代码在ASI插入分号后:*/
      function foo() {
          return;
              {
                  name: 'laoli'
              };
      }
      /* 显然不是我们的预期 */
    
  • 行的长度:为保证在编程和阅读时不那么别扭,尽量保证代码不会导致编辑器窗口横向滚动。一般风格指南中,将一行的长度限制在80个字符,如果超过80个字符,考虑在合适的位置手动换行。

    • Java语言规范中源码里单行长度不超过80个字符,文档中代码单行长度不超过70个字符
    • Android开发者编码风格指南规定单行代码长度不超过100个字符
    • 非官方的Ruby编程规范规定单行代码长度不超过80个字符
    • Python编程规范中规定单行代码长度不超过79个字符
  • 换行:主要涉及到超过上一条的一行的长度时如何缩进。在运算符后换行,下一行添加两个层级的缩进,比如规范中一个缩进是4个空格,那这里就要在下一行添加8个空格。

      /* 普通超出 */
      someHandler(arguments1, arguments2, arguments3, arguments4, arguments5,
              arguments6);
      /* if条件超出 */
      if(condition1 && condition2 && condition3 && condition4 && condition5 &&
              condition6){
          doSomething();
      }
      /* 赋值语句超出,保持和 = 右边对齐 */
      var result = something1 + something2 + something3 + something4 + something5 +
                  something6;
    
  • 空行:适当的添加空行,会大大增加代码的可读性。

    • 方法之间
    • 方法中的局部变量和第一条语句之间
    • 在多行或者单行注释之前
    • 方法内的逻辑片段之间
  • 命名:甭管大驼峰小驼峰还是匈牙利命名法。统一规范和风格最重要,在保证其他人可以通过名字很容易看得懂命名的含义的前提下,在细分场景中:

    • 变量和函数:小驼峰命名的前提下,变量保证以名词作为前缀,函数保证以动词作为前缀
    • 常量:大写字母加下滑线。虽然ES6之前并没有常量的概念,但实际开发过程中,我们依然会常常用到常量。比如规定的最大数量可以使用MAX_COUNT
    • 构造函数:大驼峰命名。构造函数是被当做JS中的类来理解的
  • 直接量

    • 字符串:无特殊命名,但有一点,换行字符串采用换行符 \ 拼接是不符合JavaScript语法的
    • 数字:采用十进制,不省略小数点前后的0
    • 对象直接量:创建对象更合适的办法是使用对象直接量,缩进及换行规则推荐如下

      var book = {
          title: 'abc',
          author: 'def'
      };
      

注释

  • 单行注释://单行注释

    • 注释单独占一行时,和上一行之间留一个空行
    • 注释单独占一行时,注释的缩进和紧接着的语句的缩进保持一致
    • 注释和代码在一行时,至少保证和代码之间有一个缩进,如果代码+注释超过了80个字符,注释尽量单独占一行
    • //尽量不要用在多行注释中
  • 多行注释:/* 多行注释 */

    • 多行注释每一行最左侧添加一个*

      /*
      * 第一段注释
      * 又一段注释
      */
      
  • 代码尾部注释不要采用多行注释
  • 何时使用注释
    • 难于理解的代码
    • 可能会被误认为错误的代码
    • 浏览器特性的hack
    • 文档注释
      • 某些自动化工具会根据注释自动生成文档
      • 所有的方法:对方法期望的参数和可能的返回值添加注释描述
      • 所有的构造函数:对自定义类型和期望的参数添加注释描述

语句和表达式

  • 所有的块语句都应当使用花括号,包括:

    • if
    • for
    • while
    • do...while...
    • try...catch
  • 花括号的对齐方式

      /* 方式1 */
      if (condition) {
          dosomething();
      } else {
          doSomethingElse();
      }
      /* 方式2 */
      if(condition)
      {
          doSomething();
      }
      else
      {
          doSomethingElse();
      }
    

    语法层面,这两对齐方式都是对的,也各有自己的习惯人群。但主流的JavaScript风格指南都推荐方式1,方式2可能会导致ASI分号插入错误导致代码不按预期执行。

  • 块语句间隔

    块语句主要有三种间隔风格,看习惯。大多数风格指南推荐风格2

      /* 风格1 */
      if(condition){
          doSomething()
      }
      /* 风格2 */
      if (condition) {
          doSomething()
      }
      /* 风格3 */
      if ( condition ) {
          doSomething()
      }
    
  • switch语句:执行完一个“case”后连续执行下一个“case”,被成为fall through,不写break即可,在某些场景下,这样操作会带来出其不意的效果,比如著名的达夫设备,但为了代码的可读性考虑,不建议使用fall through,确需使用时,必须添加对应的注释。

  • for-in循环:for-in循环一般用于对象的属性,包括实例自己的属性和从原型链继承而来的属性。在很多规范中有提到,在使用for-in循环时,需要先通过hasOwnPrototype判断是否是实例本身的属性,如果不这么做,JSHintJSLint都会提示错误。如果需要遍历包含从原型链继承而来的属性时,可以不使用hasOwnPrototype但必须添加注释说明。同时,for-in被很多的编程风格指南禁止用于数组对象,这一点也需要注意。