javascript编程风格

基本的风格化

  1. 缩进
    4个空格
  2. 行结尾
    必须以;结尾
  3. 行长度
    以不超过100个字符为宜
  4. 换行
    行超度超过100个字符,需要换行时,需要遵循以下规则:
    • 在运算符之后换行
    • 第二行添加两个缩进
    • 有一个第2条的例外,如果是赋值语句,为了程序可读性,第二行和第一行首个变量位置对齐
  5. 空行
    空行应该添加的位置:
    • 方法和方法之间
    • 函数内部局部变量和第一条语句之间
    • 单行注释和多行注释前
    • 函数内部逻辑区域之间(自行决定)
  6. 命名
    • 变量和函数使用小驼峰标示(anotherVariable)
    • 变量使用名词,函数使用动词,必须使用无意义的词
    • 常量使用大写字母加下划线标示(MAX_COUNT)
    • 构造函数使用大驼峰标示(PersonProfile),构造函数通常是名词
  7. 直接量
    javascript包含字符串、数字、布尔值、null、undefined、对象、数组直接量
    • 字符串,使用单引号,html中使用双引号
    • 字符串禁止使用多行方式,如果想使用多行,使用+运算符标示
    • 浮点数不推荐使用10.和.1形式,这种不知道是故意没写,还是忘记写了
    • 禁止使用八进制直接量,容易忽略且不常用
    • null是用来初始化一个将来可能被赋值为对象的变量,null可以理解为对象的占位符
    • 没有被初始化的变量的值为undefined,在代码中尽量避免使用undefined

注释

注释是为了更好地理解代码,在需要让代码变得更清晰的时候添加注释;也就是说在代码不够清晰时,才需要添加注释。应该使用注释的情况:

  1. 难以理解的代码

  2. 可能被误认为错误的代码,一般是非常规用法,比如while (element && (element = element[axis]))中,赋值运算用在条件判断中就很容易被理解为是===误写成了=,而编写者的原意就是赋值,这时候需要添加注释

  3. 浏览器特效hack(也可以认为是1,2的结合,既难理解,也会被误认为错误)

注释的种类

  1. 单行注释
    单行注释的格式:

    • 独占一行的注释,用来解释下一行代码,注释之前有一个空行
    • 在代码行尾部注释,代码和注释之间至少一个缩进
    • //后面跟一个空格,// 这是一个注释
    • 单行注释不应该以连续多行注释的形式出现,除非是你注释掉一大段代码
    • 注释缩进应该和要解释的代码保持一致
  2. 多行注释
    多行注释一般用于多行文本注释。格式如下:

    1
    2
    3
    4
    /*
    * 另一段注释
    * 这段注释包含两行文本
    */

    不要用多行注释注释多行代码,因为这段代码中可能包含*/,比如正则表达式/a*/或者代码中包含其他的多行注释。用单行注释来注释多行代码。

  3. 文档注释
    格式如下:

    1
    2
    3
    4
    5
    /**
    * (description)
    * @param {type} name description
    * @return {type} name description
    */

    可以用jsDoc Toolkit或者YUIDoc生成根据你的文档注释生成注释文档,用于浏览所有注释的代码。

    你应该对如下内容添加文档注释:

    • 所有的方法
    • 所有的构造函数
    • 所有包含文档化方法的对象

语句和表达式

  1. 所有的块语句都应该使用花括号,无论是块语句是包含单行还是多行代码,避免造成误解。
  2. 花括号对齐方式:

    1
    2
    3
    4
    5
    if (condition) {

    } else {

    }
  3. 块语句间隔

    • 首行前加一个空行。
    • 在左圆括号之前和右圆括号之后各添加一个空格。
      1
      2
      3
      if (condition) {
      doSomething();
      }
  4. switch语句

    • 缩进,case比switch多缩进一个层级,从第二个case开始,每个case前有一个空行

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      switch (condition) {
      case: "first":
      // 代码
      break;
      case: "second":
      // 代码
      break;
      default:
      // 代码
      break;
      }
    • case的连续执行

      允许,但是要显示说明。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      switch (condition) {
      case: "first":
      // 代码
      // fall through
      case: "second":
      // 代码
      break;
      default:
      // 代码
      break;
      }
    • default可以省略,写上注释

      1
      2
      3
      4
      5
      6
      7
      8
      9
      switch (condition) {
      case: "first":
      // 代码
      // fall through
      case: "second":
      // 代码
      break;
      // 没有default
      }
  5. with语句,禁止使用with语句,一是会造成困惑,而是会有性能问题

  6. for循环,尽可能用条件语句代替continue语句,这样更容易理解

  7. for-in循环
    for-in循环用来遍历对象的属性,包括原型继承的属性,返回属性名。

    • 如果不是要故意查找原型链,for-in尽量总是使用hasOwnProperty
    • for-in循环时用来遍历对象的,禁止用来遍历数组,可能会造成潜在的错误

变量、函数和运算符

  1. 变量
    • 所有的变量声明放到函数顶部
    • 使用单var语句, 未初始化的变量放到最后
    • 变量声明语句和之后的逻辑语句中间空一行
  2. 函数

    • 函数应该先声明后使用
    • 函数声明紧接着变量声明
    • 禁止在语句块内声明函数,不同的浏览器运行结果不一致
    • 函数的调用间隔,左括号之前没有空格,和块语句区分

      1
      doSomething(item);
    • 立即调用函数,用圆括号将函数包起来,这样看函数开头就可以识别出来这是一个立即调用表达式

      1
      2
      3
      var value = (function() {
      //代码
      }());
    • 严格模式

      • 禁止使用全局的”use strict”,这样如果是打包文件,其他文件和第三方文件很可能出错
      • 函数尽量都是用严格模式
    • 相等, 使用 === 和 !== , 禁止使用==和!=

    • 禁止使用eval,禁止向Function、setTimeout、setInterval注入可执行字符串,如果实在要用,推荐使用eval()

  3. 原始包装类型
    在javascript中你使用原始值(String、Boolean、Number),实际上是使用的原始包装对象,这是因为javascript引擎在背后调用了对于的原始类型构造函数包装该该初始值,所以你可以这样用:

    1
    2
    var name = "Nicholas";
    console.log(name.toUpperCase());

    有一点要注意,js引擎在遇到原始值时会自动创建这个原始值的原始包装对象,在执行完该语句时随即销毁,下次遇到再重新构建,所以你给一个字符串添加对象是读不到的:

    1
    2
    3
    var name = "Nicholas";
    name.author = true;
    console.log(name.author); //undefined

    正是由于这个原因,在使用原始值和由原始类型构造函数创建出来的值是有区别的,而且使用原始类型构造函数创建原始值又繁琐,所以应该禁止使用String、Number和Boolean创建新对象。