CoffeeScript provides three keywords which translate to JavaScript's true
keyword (yes
, on
, true
), and three which translate to JavaScript's
false
keyword (no
, off
, false
).
Use whichever reads best (usually yes
or no
).
Never begin a number literal with a period (.
):
right = 0.5
wrong = .5
# ^ number literals should not begin with "."
Omit the sign for positive numbers:
right = 42
wrong = +42
# ^ unnecessary sign
Don't include a space between sign and number:
right = -42
wrong = - 42
# ^ unwanted space after sign
Use binary literal notation for bitmasks:
right = permissions = 0b101
wrong = permissions = 5
Don't simplify an arithmetic expression if its meaning would be obscured:
right = 24 * 60 * 60 * 1000
wrong = 86400000
Favor single quotes:
right = 'Hello, world!'
wrong = "Hello, world!"
# ^ unnecessarily double-quoted string
Double quotes should be used to avoid having to escape single quotes ('
):
right = "It's a beautiful day, isn't it?"
wrong = 'It\'s a beautiful day, isn\'t it?'
# ^ avoidable backslash (use double-quoted string)
Consider block strings for strings containing both single and double quotes:
right = '''"Don't do that!", said the boy's mother.'''
wrong = '"Don\'t do that!", said the boy\'s mother.'
# ^ avoidable backslash (use block string)
Use interpolation rather than concatenation:
right = "Hello, #{user.firstName}!"
wrong = 'Hello, ' + user.firstName + '!'
Backslashes harm readability and should be avoided. Use a character class when
matching a literal period (.
), and consider the extended form when matching
several slashes (/
):
right = /// ^https?://upthere[.]com$ ///
wrong = /^https?:\/\/upthere\.com$/
# ^ avoidable backslash (use heregex)
Include comments for complex patterns:
re = ///
^
(\d{4})-(\d\d)-(\d\d) # year-month-date
[T\x20] # "T" or " "
(\d\d):(\d\d) # hours:minutes
(?::(\d\d)(?:[.](\d+))?)? # seconds with optional decimal component
(?:([-+]\d\d):?(\d\d)|Z) # time zone offset
$
///
Since spaces are ignored in heregexes, \x20
should be used to match a
literal space (
).
There should be no spaces after the opening square bracket ([
) or before the
closing square bracket (]
):
right = [1, 2, 3]
wrong = [ 1, 2, 3 ]
# ^ unwanted space after "["
Separate items in single-line array literals with a comma (,
) followed by a
space (
):
right = [1, 2, 3]
wrong = [1,2,3]
# ^ missing space after ","
wrong = [1 , 2 , 3]
# ^ unwanted space before ","
Omit commas in multi-line array literals:
right = [
'foo'
'bar'
'baz'
]
wrong = [
'foo',
# ^ unwanted comma
'bar',
# ^ unwanted comma
'baz'
]
There should be no spaces after the opening curly bracket ({
) or before the
closing curly bracket (}
):
right = {foo: 1, bar: 2}
wrong = { foo: 1, bar: 2 }
# ^ unwanted space after "{"
Separate key and value with a colon (:
) followed by a space (
):
right = foo: 1, bar: 2
wrong = foo:1, bar:2
# ^ missing space after ":"
wrong = foo : 1, bar : 2
# ^ unwanted space before ":"
Separate entries in single-line object literals with a comma (,
) followed by
a space (
):
right = foo: 1, bar: 2
wrong = foo: 1,bar: 2
# ^ missing space after ","
wrong = foo: 1 , bar: 2
# ^ unwanted space before ","
Omit commas in multi-line object literals:
right =
foo: yes
bar: yes
baz: 42
wrong =
foo: yes,
# ^ unwanted comma
bar: yes,
# ^ unwanted comma
baz: 42
For certain operators, a space (
) should be included between operator and
operand(s). This section demonstrates the preferred spacing for each operator.
delete y.z
typeof x
++x
--x
+x
-x
~x
!x
not x
# Multiplicative operators
x * y
x / y
x % y
# Additive operators
x + y
x - y
# Bitwise shift operators
x << y
x >> y
x >>> y
# Relational operators
x < y
x > y
x <= y
x >= y
x instanceof y
x of y
x in y
x == y ; x is y # favor "is"
x != y ; x isnt y # favor "isnt"
# Binary bitwise operators
x & y
x ^ y
x | y
# Binary logical operators
x && y ; x and y # favor "and"
x || y ; x or y # favor "or"
Use is
and isnt
rather than ==
and !=
. Rationale: CoffeeScript's ==
is different from JavaScript's ==
, whereas is
doesn't exist in JavaScript
so cannot cause confusion.
When comparing a variable against a set of values, use in
:
right = location.protocol in ['http:', 'https:']
wrong = location.protocol is 'http:' or location.protocol is 'https:'
# ^^^^^^^^^^^^^^^^^^^^ unwanted repetition
When checking whether a variable falls within a range of values, use chained comparison:
right = 200 <= res.statusCode <= 299
wrong = res.statusCode >= 200 and res.statusCode <= 299
# ^^^^^^^^^^^^^^ unwanted repetition
Use postfix if
for one-liners:
right = true if cond
if cond then wrong = true
# ^^^^ then clause with no else clause
Use of
for membership checks:
right = true if 'foo' of cache
wrong = true if cache.foo
Use "#{...}"
to stringify values:
right = "#{x}"
wrong = x.toString()
Use @
in place of this.
:
right = "#{@firstName} #{@lastName}"
wrong = "#{this.firstName} #{this.lastName}"
# ^^^^^ expected "@" shorthand
Don't use @
in place of this
:
right = this
wrong = @
# ^ naked "@" (use "this" instead)
Use ::
in place of .prototype.
:
right = Object::hasOwnProperty
wrong = Object.prototype.hasOwnProperty
# ^^^^^^^^^^^ expected "::" shorthand
Don't use ::
in place of .prototype
:
right = Object.prototype
wrong = Object::
# ^^ dangling "::" (use ".prototype" instead)
Use @
to assign static properties to a class:
# right
class Foo
@bar = 42
# wrong
class Foo
Foo.bar = 42
# ^^^^ expected "@" shorthand
Use the fat arrow (=>
) to preserve context:
# right
setTimeout =>
@dismiss()
, 1000
# wrong
self = this
setTimeout ->
self.dismiss()
, 1000