My JavaScript Coding Styleguide
本文定义了个人的JavaScript编码规范。
前提说明
- 必须指代MUST,拥有强制性
- 不得指代MUST NOT,拥有强制性
- 应当指代SHOULD,不拥有强制性但建议实施,建议个人根据需求进一步明确定义
- 可以指代MAY,不拥有强制性但建议实施,建议个人根据需求进一步明确定义
行长度
每一行代码严格以80字符为最大长度,即一行包括前后的空格,不得超过80个字符。
由于必定存在一些特殊的原因,导致一条语句的长度超过80,应当按以下原则进行切分:
字符串过长
按一定长度截断字符串,并使用+
运算符进行连接。分隔字符串尽量按语音进行,如不要在一个完整的名词中间断开。
特别的,对于HTML片段的拼接,通过缩进,保持和HTML相同的结构:
也可使用数组来进行拼接,相对+
运算更容易调整缩进:
函数调用时参数过多
当参数过多,在一行书写函数调用语句会超过80个字符的限制时,应当将每个参数独立写在一行上,并将结束的右括号)
独立一行,所有参数增加一个缩进,以控制每行的长度,如:
当参数较多,一行一个书写会导致过长时,应当按逻辑对参数进行组合,最经典的是jQuery.format
函数,如:
三元运算符过长
三元运算符由3部分组成,因此其换行应当根据每个部分的长度不同,形成3种不同的情况:
不得出现以下情况:
这种方法会导致语义上的分裂,即条件和分支在一行,另一分支在一行,没有按逻辑进行组织。
过长的逻辑条件组合
当因为较复杂的逻辑条件组合导致80个字符无法满足需求时,考虑将每个条件独立一行,逻辑运算符放置在行尾或行首进行分隔,或将部分逻辑按逻辑组合进行分隔,最终将右括号)
与左大括号{
放在独立一行,如:
空格
在特定的位置加上空格有助于代码的可读性,以下位置必须加上空格:
- 除括号外,所有运算符的前后,如
+
, -
等等
- 用作代码块起始的左大括号
{
前,包括if
、else
、try
、finally
这些关键字之后,以及函数定义的参数列表之后
- 以下关键字之后:
for
、switch
、while
- 对象初始化(
{ ... }
)的每个属性名的冒号:
后
- 所有逗号
,
后
- 单行的对象初始化(
{ ... }
)左大括号{
后和右大括号}
前
注意,在函数参数列表之前不得加上空格,以下是一个函数的正确声明方式:
对齐和缩进
严格采用4个空格为一次缩进,不得采用TAB作为缩进。在以下情况下必须缩进:
- 一个代码块与其父代码块相比必须多一次缩进
- 未结束的语句在换行后必须多一次缩进
switch
下的case
和default
必须缩进
缩进会带来自然的对齐,在缩进之外,不需要额外的对齐:
- 多个变量声明时,不得对齐
=
符号
- 初始化对象时,不得对齐
:
符号
换行
在以下位置必须换行:
- 每个独立语句结束后
if
、else
、catch
、finally
、while
等关键字前
- 运算符处换行时,运算符必须在新行的行首
对于因为单行长度超过限制时产生的换行,参考行长度中的策略进行分隔。
除此之外,存在额外的策略:
过长的JSON和数组
如果对象属性较多导致每个属性一行占用空间过大,可以按语义或逻辑进行分组的组织,如:
通过5个一组的分组,将每一行控制在合理的范围内,并且按逻辑进行了切分。
对于项目较多的数组,也可以采用相同的方法,如:
单行和跨行参数混用
当函数调用时,传递的参数大于或等于2个,且有一个或以上参数跨越多行时,要求每一个参数独立一行,这通常出现在匿名函数或者对象初始化等作为参数时,如setTimeout
函数等:
如果认为每个参数单独一行占用过多的空间,则应当将跨域多行的参数独立出来为一个变量:
数组和对象初始化的混用
严格按照每个对象的起始{
和结束}
在独立一行的风格书写,如:
空行
在代码规范中最容易被人忽略的就是空行。一般来说,代码应该看起来就像一篇如行云流水般的文章,
而不是一篇用连续的用文字堆砌起来的文本。空行就是用来区分相关行和非相关行代码的。
在以下位置必须添加空行:
- 每个方法之间
- 每个方法的本地变量和它的第一个语句之间
- 多行或单行注释之前
- 每个独立语句结束后
- 每个流程控制语句之前,比如
if
、else
、catch
、finally
、while
等关键字前
命名
命名的方法通常有以下几类:
- Camel命名法,形如
thisIsAnApple
- Pascal命名法,形如
ThisIsAnApple
- 下划线命名法,形如
this_is_an_apple
- 中划线命名法,形如
this-is-an-apple
根据不同类型的内容,采用不同的命名法:
- 变量名,使用Camel命名法
- 参数名,使用Camel命名法
- 函数名,使用Camel命名法
- 方法/属性,使用Camel命名法
- 私有(保护)属性、函数以下划线
_
开头
- 常量名,使用全部大写的下划线命名法,如
IS_DEBUG_ENABLED
- 类名,使用Pascal命名法
- 枚举名,使用Pascal命名法
- 枚举的属性,使用全部大写的下划线命名法
- 命名空间,使用Camel命名法
命名同时还需要关注语义,如:
- 变量名应当使用名词
- Boolean类型的应当使用is、has等起头,表示其类型
- 函数名应当使用动宾短语
- 类名用应当使用名词
语法
变量声明
一个var
关键字必须只声明一个变量。
变量必须即用即声明,不得在函数(或其它形式的代码块)起始位置统一声明所有变量。
字符串
字符串必须使用单引号'
。
对象和数组
对象和数组优先使用其初始化器({ ... }
和[ ... ]
)声明,不要使用new Object
和new Array
。
如果一个对象的所有属性名均不是保留字,则该对象声明时,所有属性名不得添加引号,这包括属性名是数字的情况。
如果一个对象的属性名有一个或多个是保留字,则该对象声明时,所有属性名必须添加引号。
异常
允许使用异常,但在创建Error
对象时,必须明确地传递message
参数。
继承
采用jQuery.inherit
或相似机制实现继承,不得随意覆盖prototype
属性。
声明类的方法时,采用MyClass.prototype.foo = function() {}
的形式,不得直接覆盖prototype
属性。
其它
修改内置原型
需要修改内置对象的原型时,该代码必须由一个高级别工程师进行Review。
eval
和with
当代码中使用eval
或with
时,该代码必须由一个同级别工程师和一个高级别工程师进行Review。
Related Posts
Xin(Khalil) Zhang
19 January 2015