Use spaces only, with 2 spaces per indentation level. Never mix tabs and spaces.
### Maximum Line LengthLimit all lines to a maximum of 80 characters.
### Blank LinesSeparate top-level function and class definitions with a single blank line.
Separate method definitions inside of a class with a single blank line.
Use a single blank line within the bodies of methods or functions in cases where this improves readability (e.g., for the purpose of delineating logical sections).
### Trailing WhitespaceDo not include trailing whitespace on any lines.
### EncodingUTF-8 is the preferred source file encoding.
## Module ImportsIf using a module system (CommonJS Modules, AMD, etc.), require
statements should be placed on separate lines.
require 'lib/setup'
Backbone = require 'backbone'
These statements should be grouped in the following order:
- Standard library imports (if a standard library exists)
- Third party library imports
- Local imports (imports specific to this application or library)
Avoid extraneous whitespace in the following situations:
-
Immediately inside parentheses, brackets or braces
($ 'body') # Yes ( $ 'body' ) # No
-
Immediately before a comma
console.log x, y # Yes console.log x , y # No
Additional recommendations:
-
Always surround these binary operators with a single space on either side
-
assignment:
=
-
Note that this also applies when indicating default parameter value(s) in a function declaration
test: (param = null) -> # Yes test: (param=null) -> # No
-
-
augmented assignment:
+=
,-=
, etc. -
comparisons:
==
,<
,>
,<=
,>=
,unless
, etc. -
arithmetic operators:
+
,-
,*
,/
, etc. -
(Do not use more than one space around these operators)
# Yes x = 1 y = 1 fooBar = 3 # No x = 1 y = 1 fooBar = 3
-
Use camelCase
(with a leading lowercase character) to name all variables, methods, and object properties.
Use CamelCase
(with a leading uppercase character) to name all classes. (This style is also commonly referred to as PascalCase
, CamelCaps
, or CapWords
, among other alternatives.)
(The official CoffeeScript convention is camelcase, because this simplifies interoperability with JavaScript. For more on this decision, see here.)
For constants, use all uppercase with underscores:
CONSTANT_LIKE_THIS
Methods and variables that are intended to be "private" should begin with a leading underscore:
_privateMethod: ->
(These guidelines also apply to the methods of a class.)
When declaring a function that takes arguments, always use a single space after the closing parenthesis of the arguments list:
foo = (arg1, arg2) -> # Yes
foo = (arg1, arg2)-> # No
Do not use parentheses when declaring functions that take no arguments:
bar = -> # Yes
bar = () -> # No
In cases where method calls are being chained and the code does not fit on a single line, each call should be placed on a separate line and indented by one level (i.e., two spaces), with a leading .
.
[1..3]
.map((x) -> x * x)
.concat([10..12])
.filter((x) -> x < 11)
.reduce((x, y) -> x + y)
When calling a function if it has at least one argument you should omit parentheses:
baz 12
If it has no arguments, but we are going to use a returning value, you should use parentheses
res = baz()
If it has no arguments and we do not care about returning value you should use do:
do baz
When chainging functions use parentheses:
foo(4).bar(8)
Remember, it's better to omit parentheses, because it is the coffeescript way to do stuff, but try to keep code readable:
print inspect value
new Tag new Value(a, b), new Arg(c)
Use string interpolation instead of string concatenation:
"this is an #{adjective} string" # Yes
"this is an " + adjective + " string" # No
Prefer single quoted strings (''
) instead of double quoted (""
) strings, unless features like string interpolation are being used for the given string.
If you have one line expression use post-condition:
do anything unless something
Try to avoid not keyword if possible using if or unless:
just = true
#good
if just
test 1
foo 2
unless just
test 3
foo 4
#bad
if not just
test 3
foo 4
Multi-line if/else clauses should use indentation:
# Yes
if true
...
else
...
# No
if true then ...
else ...
Take advantage of comprehensions whenever possible:
# Yes
result = (item.name for item in array)
# No
results = []
for item in array
results.push item.name
To filter:
result = (item for item in array when item.name is "test")
To iterate over the keys and values of objects:
object = one: 1, two: 2
alert("#{key} = #{value}") for key, value of object
Use annotations when necessary to describe a specific action that must be taken against the indicated block of code.
Write the annotation on the line immediately above the code that the annotation is describing.
The annotation keyword should be followed by a colon and a space, and a descriptive note.
# FIXME: The client's current state should *not* affect payload processing.
resetClientState()
processPayload()
If multiple lines are required by the description, indent subsequent lines with two spaces:
# TODO: Ensure that the value returned by this call falls within a certain
# range, or throw an exception.
analyze()
Annotation types:
TODO
: describe missing functionality that should be added at a later dateFIXME
: describe broken code that must be fixedOPTIMIZE
: describe code that is inefficient and may become a bottleneckHACK
: describe the use of a questionable (or ingenious) coding practiceREVIEW
: describe code that should be reviewed to confirm implementation
If a custom annotation is required, the annotation should be documented in the project's README.
## Miscellaneousand
is preferred over &&
.
or
is preferred over ||
.
is
is preferred over ==
.
not
is preferred over !
.
or=
should be used when possible:
temp or= {} # Yes
temp = temp || {} # No
Prefer shorthand notation (::
) for accessing an object's prototype:
Array::slice # Yes
Array.prototype.slice # No
Prefer @property
over this.property
.
@property # Yes
this.property # No
Always prefer @
over this
.
res = ->
@
Avoid return
where not required.
Use splats (...
) when working with functions that accept variable numbers of arguments:
console.log args... # Yes
(a, b, c, rest...) -> # Yes