這份指南闡述了一些 CoffeeScript 的最佳實踐和編碼慣例。javascript
這份指南是社羣驅動的,很是鼓勵你們來貢獻內容。html
請注意這仍是一份正在完善的指南:仍有不少地方能夠改進,有些已制定的準則也不必定是社區慣用的(基於此,在適當的狀況下,這些有待斟酌的準則將有可能被修改或刪除。)java
本指南中的不少細節受到了幾份現有的風格指南和其餘資源的啓發。特別是:python
只用 空格,每級縮進均爲 2 個空格。切勿混用 Tab 和空格。git
限制每行最多 79 個字符。github
頂級函數和類的定義用一個空行分開。數組
類內部的函數定義也用一個空行分開。ruby
對於每一個函數體內,只在爲了提升可讀性的狀況下才使用一個空行(例如:爲了達到劃分邏輯的目的)。less
不要在任何一行保留行尾空白。ide
當對象(或數組)的屬性(或元素)做爲單獨一行列出時,避免在換行符前使用逗號。以下:
# 好 foo = [ 'some' 'string' 'values' ] bar: label: 'test' value: 87 # 差 foo = [ 'some', 'string', 'values' ] bar: label: 'test', value: 87
UTF-8 是首選的源文件編碼。
若是須要導入模塊 (CommonJS 模塊,AMD,等等.), require
語句應該單獨做爲一行。以下:
require 'lib/setup' Backbone = require 'backbone'
這些語句應該按如下順序去分組:
下列狀況應該避免多餘的空格:
緊貼着圓括號、方括號和大括號內部
($ 'body') # 好 ( $ 'body' ) # 差
緊貼在逗號前
console.log x, y # 好 console.log x , y # 差
額外建議:
在下列二元操做符的左右兩邊都保留 一個空格
賦值運算符: =
注意這一樣適用於函數定義中的默認參數
test: (param = null) -> # 好 test: (param=null) -> # 差
自增運算符: +=
, -=
, 等等。
==
, <
, >
, <=
, >=
, unless
, 等等。算術運算符: +
, -
, *
, /
, 等等。
(這些操做符兩邊的空格不要多於一個)
# 好 x = 1 y = 1 fooBar = 3 # 差 x = 1 y = 1 fooBar = 3
若是你修改了一段已有註釋說明的代碼,則也要更新它對應的註釋。(理想狀態是,重構這段代碼直到它不須要註釋說明,而後再把以前的註釋全刪掉。)
註釋的首字母要大寫,除非第一個單詞是以小寫字母開頭的標識符。
若是註釋很短,能夠省略末尾的句號。
註釋塊一般應用於尾隨其後的一段代碼。
每一行註釋都以 #
加一個空格開頭,並且和被註釋的代碼有相同的縮進層次。
註釋塊內的段落以僅含單個 #
的行分割。
# 這是一個塊註釋。請注意假如這是一段塊註釋, # 則它描述的就應該是接下來的這段代碼。 # # 這是塊註釋的第二段。 # 請注意這段是由上一行帶有 # 號的空行分開的。(P.S. 最好用英文寫註釋) init() start() stop()
行內註釋緊貼在被描述的代碼的上一行,若是行內註釋足夠短,則能夠處在同一行行尾(由一個空格隔開)。
全部行內註釋都以 #
加一個空格開頭。
應該限制行內註釋的使用,由於它們的存在一般是一個代碼異味的標誌。
不要給顯而易見的狀況做行內註釋:
# 差 x = x + 1 # x 自增
然而,行內註釋在某些狀況下是有用的:
# 好 x = x + 1 # 邊界補足
使用 小駝峯命名法
(第一個詞的首字母小寫,後面每一個詞的首字母大寫)來命名全部的變量、方法和對象屬性。
使用 大駝峯命名法
(第一個詞的首字母,以及後面每一個詞的首字母都大寫)來命名全部的類 (在其餘相似的命名法中,這種風格一般也被稱爲 帕斯卡命名法(PascalCase)
、 大寫駝峯命名法(CamelCaps)
或 首字母大寫命名法(CapWords)
。)
(CoffeeScript 官方 約定是用駝峯命名法,由於這能夠簡化與 JavaScript 的相互轉化,想了解更多,請看這裏.)
對於常量,單詞所有大寫,用下劃線隔開便可:
CONSTANT_LIKE_THIS
私有函數和私有變量都應該在前面加一個下劃線:
_privateMethod: ->
(如下這些準則一樣適用於類中的方法。)
當聲明一個帶參函數時,應在參數列表的右圓括號後空出一個空格:
foo = (arg1, arg2) -> # 好 foo = (arg1, arg2)-> # 差
無參函數不要用圓括號:
bar = -> # 好 bar = () -> # 差
當函數鏈式調用,卻在一行放不下時,則把每一個函數調用都另起一行,且都縮進一級(即在 .
前加兩個空格)。
[1..3] .map((x) -> x * x) .concat([10..12]) .filter((x) -> x < 11) .reduce((x, y) -> x + y)
當調用函數時,咱們應該爲了提升可讀性而去掉圓括號。請記住,「可讀性」是咱們主觀臆斷的。只有相似下面幾個例子的狀況才被社區認爲是最佳的:
baz 12 brush.ellipse x: 10, y: 20 # 大括號在適當的時候也能夠去掉 foo(4).bar(8) obj.value(10, 20) / obj.value(20, 10) print inspect value new Tag(new Value(a, b), new Arg(c))
有時候你會發現圓括號用來包裹的是函數體(而不是函數的參數)。請看下面的例子(如下簡稱爲「函數體風格」):
($ '#selektor').addClass 'klass' (foo 4).bar 8
這段代碼會編譯爲:
$('#selektor').addClass 'klass' foo(4).bar 8
一些習慣鏈式調用的人會巧用「函數體風格」進行單獨初始化:
($ '#selektor').addClass('klass').hide() # 單獨初始化調用 (($ '#selektor').addClass 'klass').hide() # 所有調用
「函數體風格」並不獲得推薦。可是, 當它適應一些特殊的項目需求時,仍是得用它。
用字符串插值代替字符串鏈接符:
"this is an #{adjective} string" # 好 "this is an " + adjective + " string" # 差
最好用單引號 (''
) 而不是雙引號 (""
) 。除非是插入到另外一段現有的字符串中(相似字符串插值)。
用 unless
來代替 if
的否認狀況。
不要用 unless...else
, 而用 if...else
:
# 好 if true ... else ... # 差 unless false ... else ...
多行的 if/else 語句應該縮進:
# 好 if true ... else ... # 差 if true then ... else ...
儘量的使用列表解析:
# 好 result = (item.name for item in array) # 差 results = [] for item in array results.push item.name
還能夠過濾結果:
result = (item for item in array when item.name is "test")
遍歷對象的鍵值:
object = one: 1, two: 2 alert("#{key} = #{value}") for key, value of object
不要修改本地對象。
好比,不要給 Array.prototype
引入 Array#forEach
。
不要抑制異常拋出。
必要的時候應該寫註解,來指明接下來的代碼塊具體將幹什麼。
註解應緊貼在被描述代碼的上一行。
註解關鍵字後面應該跟一個冒號加一個空格,加一個描述性的註釋。
# FIXME: The client's current state should *not* affect payload processing. resetClientState() processPayload()
若是註解不止一行,則下一行縮進兩個空格。
# TODO: Ensure that the value returned by this call falls within a certain # range, or throw an exception. analyze()
註解有如下幾類:
TODO
: 描述缺失的功能,以便往後加入FIXME
: 描述須要修復的代碼OPTIMIZE
: 描述性能低下,或難以優化的代碼HACK
: 描述一段值得質疑(或很巧妙)的代碼REVIEW
: 描述須要確認其編碼意圖是否正確的代碼若是你必須自定義一個新的註解類型,則應該把這個註解類型記錄在項目的 README 裏面。
and
更優於 &&
.
or
更優於 ||
.
is
更優於 ==
.
not
更優於 !
.
or=
應在可能的狀況下使用:
temp or= {} # 好 temp = temp || {} # 差
最好用 (::
) 訪問對象的原型:
Array::slice # 好 Array.prototype.slice # 差
最好用 @property
而不是 this.property
.
return @property # 好 return this.property # 差
可是,避免使用 單獨的 @
:
return this # 好 return @ # 差
沒有返回值的時候避免使用 return
,其餘狀況則須要顯示 return 。
當函數須要接收可變數量的參數時,使用 splats (...
)。
console.log args... # 好 (a, b, c, rest...) -> # 好
(譯文完)