??
这份指南阐述了一些 CoffeeScript 的最佳实践和编码惯例。
这份指南是社群驱动的,非常鼓励大家来贡献内容。
请注意这还是一份正在完善的指南:仍有很多地方可以改进,有些已制定的准则也不一定是社区惯用的(基于此,在适当的情况下,这些有待斟酌的准则将有可能被修改或删除。)
灵感
本指南中的很多细节受到了几份现有的风格指南和其他资源的启发。特别是:
- PEP-8: Style Guide for Python Code
- Bozhidar Batsov’s Ruby Style Guide
- Google’s JavaScript Style Guide
- Common CoffeeScript Idioms
- Thomas Reynolds’ CoffeeScript-specific Style Guide
- Jeremy Ashkenas’ code review of Spine
- The CoffeeScript FAQ
代码布局(Code Layout)
Tab 还是 空格?(Tabs or Spaces?)
只用 空格,每级缩进均为 2 个空格。切勿混用 Tab 和空格。
最大行宽(Maximum Line Length)
限制每行最多 79 个字符。
空行(Blank Lines)
- 顶级函数和类的定义用一个空行分开。
- 类内部的函数定义也用一个空行分开。
- 对于每个函数体内,只在为了提高可读性的情况下才使用一个空行(例如:为了达到划分逻辑的目的)。
结尾空白(Trailing Whitespace)
不要在任何一行保留行尾空白。
可选的逗号(Optional Commas)
当对象(或数组)的属性(或元素)作为单独一行列出时,避免在换行符前使用逗号。如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
编码(Encoding)
UTF-8 是首选的源文件编码。
模块导入(Module Imports)
如果需要导入模块 (CommonJS 模块,AMD,等等.), require
语句应该单独作为一行。如下:
1 2 |
|
这些语句应该按以下顺序去分组:
- 标准库的导入 (如果标准库存在)
- 第三方库的导入
- 本地导入 (导入这个应用程序的或库的具体依赖)
表达式和语句中的空白(Whitespace in Expressions and Statements)
下列情况应该避免多余的空格:
- 紧贴着圆括号、方括号和大括号内部
1 2 |
|
紧贴在逗号前
1 2 |
|
额外建议:
- 在下列二元操作符的左右两边都保留 一个空格
- 赋值运算符:
=
注意:这同样适用于函数定义中的默认参数
- 赋值运算符:
1 2 |
|
- 自增运算符:
+=
,-=
, 等等。 - 比较运算符:
==
,<
,>
,<=
,>=
,unless
, 等等。 - 算术运算符:
+
,-
,*
,/
, 等等。 - (这些操作符两边的空格不要多于一个)
1 2 3 4 5 6 7 8 9 |
|
注释(Comments)
如果你修改了一段已有注释说明的代码,则也要更新它对应的注释。(理想状态是,重构这段代码直到它不需要注释说明,然后再把之前的注释全删掉。)
注释的首字母要大写,除非第一个单词是以小写字母开头的标识符。
如果注释很短,可以省略末尾的句号。
块注释(Block Comments)
注释块通常应用于尾随其后的一段代码。
每一行注释都以 #
加一个空格开头,而且和被注释的代码有相同的缩进层次。
注释块内的段落以仅含单个 #
的行分割。
1 2 3 4 5 6 7 8 9 |
|
行内注释(Inline Comments)
行内注释紧贴在被描述的代码的上一行,如果行内注释足够短,则可以处在同一行行尾(由一个空格隔开)。
所有行内注释都以 #
加一个空格开头。
应该限制行内注释的使用,因为它们的存在通常是一个代码异味的标志。
不要给显而易见的情况作行内注释:
1 2 |
|
然而,行内注释在某些情况下是有用的:
1 2 |
|
命名规范(Naming Conventions)
使用 小驼峰命名法
(第一个词的首字母小写,后面每个词的首字母大写)来命名所有的变量、方法和对象属性。
使用 大驼峰命名法
(第一个词的首字母,以及后面每个词的首字母都大写)来命名所有的类 (在其他类似的命名法中,这种风格通常也被称为 帕斯卡命名法(PascalCase)
、 大写驼峰命名法(CamelCaps)
或 首字母大写命名法(CapWords)
。)
(CoffeeScript 官方 约定是用驼峰命名法,因为这可以简化与 JavaScript 的相互转化,想了解更多,请看这里.)
对于常量,单词全部大写,用下划线隔开即可:
1 |
|
私有函数和私有变量都应该在前面加一个下划线:
1 |
|
函数(Functions)
(以下这些准则同样适用于类中的方法。)
当声明一个带参函数时,应在参数列表的右圆括号后空出一个空格:
1 2 |
|
无参函数不要用圆括号:
1 2 |
|
当函数链式调用,却在一行放不下时,则把每个函数调用都另起一行,且都缩进一级(即在 .
前加两个空格)。
1 2 3 4 5 |
|
当调用函数时,我们应该为了提高可读性而去掉圆括号。请记住,「可读性」是我们主观臆断的。只有类似下面几个例子的情况才被社区认为是最佳的:
1 2 3 4 5 6 7 8 9 10 11 |
|
有时候你会发现圆括号用来包裹的是函数体(而不是函数的参数)。请看下面的例子(以下简称为「函数体风格」):
1 2 3 |
|
这段代码会编译为:
1 2 3 |
|
一些习惯链式调用的人会巧用「函数体风格」进行单独初始化:
1 2 |
|
「函数体风格」并不得到推荐。但是, 当它适应一些特殊的项目需求时,还是得用它。
字符串(Strings)
用字符串插值代替字符串连接符:
1 2 |
|
最好用单引号 (‘‘
) 而不是双引号 (""
) 。除非是插入到另一段现有的字符串中(类似字符串插值)
条件判断(Conditionals)
用 unless
来代替 if
的否定情况。
不要用 unless...else
, 而用 if...else
:
1 2 3 4 5 6 7 8 9 10 11 |
|
多行的 if/else 语句应该缩进:
1 2 3 4 5 6 7 8 9 |
|
循环和列表解析(Looping and Comprehensions)
尽可能的使用列表解析:
1 2 3 4 5 6 7 |
|
还可以过滤结果:
1 |
|
遍历对象的键值:
1 2 |
|
扩展本地对象(Extending Native Objects)
不要修改本地对象。
比如,不要给 Array.prototype
引入 Array#forEach
。
异常(Exceptions)
不要抑制异常抛出。
注解(Annotations)
必要的时候应该写注解,来指明接下来的代码块具体将干什么。
注解应紧贴在被描述代码的上一行。
注解关键字后面应该跟一个冒号加一个空格,加一个描述性的注释。
1 2 3 |
|
如果注解不止一行,则下一行缩进两个空格。
1 2 3 |
|
注解有以下几类:
TODO
: 描述缺失的功能,以便日后加入FIXME
: 描述需要修复的代码OPTIMIZE
: 描述性能低下,或难以优化的代码HACK
: 描述一段值得质疑(或很巧妙)的代码REVIEW
: 描述需要确认其编码意图是否正确的代码
如果你必须自定义一个新的注解类型,则应该把这个注解类型记录在项目的 README 里面。
其他(Miscellaneous)
and
更优于 &&
.
or
更优于 ||
.
is
更优于 ==
.
not
更优于 !
.
or=
应在可能的情况下使用:
1 2 |
|
最好用 (::
) 访问对象的原型:
1 2 |
|
最好用 @property
而不是 this.property
.
1 2 |
|
但是,避免使用 单独的 @
:
1 2 |
|
没有返回值的时候避免使用 return
,其他情况则需要显示 return 。
当函数需要接收可变数量的参数时,使用 splats (...
)。
1 2 3 |
|