CoffeeScript Style Guide to maintain readable code, that looks like it was written by one person, even if a whole team was working on it. Highly inspired by Airbnb JavaScript Style Guide
- CoffeeScript syntax
- Tabs
- Whitespace
- Semicolons
- Commas
- Naming conventions
- Variables
- Objects
- Accessors
- Arrays
- Strings
- Events
- Functions
- Iterators
- Type casting
- Comparison Operators & Equality
- Comments
- jQuery
- 1.1 Do not use braces
(
for function calls with parameters.
createPerson = (name) ->
console.log 'Created!'
createPerson 'John Doe'
showMessage = ->
console.log 'This is a message'
showMessage()
- 1.2 Do not use curly braces
{
for declaring objects.
person =
name: 'John Doe'
- 1.3 Use curly braces
{
for declaring empty objects.
emptyObject = {}
- 1.4 Use the
class
keyword to create classes, instead of working directly withprototype
.
class Person
constructor: ->
console.log 'Person constructed!'
- 1.5 Do not use braces
(
for empty parameter lists.
emptyParameterListFunction = ->
console.log 'I have no parameters and no braces'
- 3.1 Place one space after the trailing brace.
addition = (a, b) ->
console.log a + b
- 3.2 Set off operators with spaces.
x = 1 + 2
- 3.3 Use indentation when making long method chains. Use a leading dot, which emphasizes that the line is a method call, not a new statement.
$('.items')
.addClass '.additional-class'
.attr 'width', '110'
.attr 'height', '150'
- 4.1 Don't use them.
age = 21 # Don't use semicolons
- 5.1 Don't use commas at all.
numbers = [
1
2
3
]
mapping =
a: 1
b: 2
c: 3
- 6.1 Use camelCase when naming objects, functions, variables, and instances.
firstName = 'John'
myObject = {}
testFunction = ->
return
- 6.2 Use SNAKE_CASE and uppercase for constants.
API_URL = '/api'
- 6.3 Use PascalCase when naming classes.
self = undefined
class Person
name: 'John Doe'
constructor: (options) ->
self = @
self.name = options.name
- 6.4 Use a leading underscore
_
when naming private properties.
@_firstName = 'John'
- 6.5 Don't use reserved words.
# bad
default = 42
# good
defaultNumber = 42
- 7.1 Because CoffeeScript knows no
var
keyword, variables are always declared without it. If you want to declare global variables, use thewindow
object.
name = 'John Doe'
window.env = 'local'
- 8.1 Use the literal syntax for object creation.
person =
name: 'John Doe'
- 8.2 Methods can return this to help with method chaining.
class Person
walk: (meters) ->
console.log 'I walked ${meters}m'
return @
jump: ->
console.log 'I jumped very high'
return @
person = new Person()
person.walk()
.jump()
- 8.3 Use dot notation when accessing properties.
person =
name: 'John Doe'
name = person.name
- 8.4 Use subscript notation
[]
when accessing properties with a variable.
person =
name: 'John Doe'
property = 'name'
name = person[property]
- 8.5 Use
@
instead ofthis
.
self = undefined
class Person
name: ''
constructor: (options) ->
self = @
- 8.5 Use a variable called
self
to refer to thethis
context of objects.
self = undefined
class Person
name: ''
constructor: (options) ->
self = @
self.name = options.name
-
9.1 Accessor functions for properties are not required.
-
9.2 If you do make accessor functions use
getVal()
andsetVal('hello')
.
person.setAge 21
age = person.getAge()
- 9.3 If the property is a
boolean
, useisVal()
orhasVal()
.
if person.hasCoffee()
console.log 'I am alive'
if person.isAlive()
console.log 'I have coffee'
- 9.4 It's okay to create
get()
andset()
functions, but be consistent.
self = undefined
class Person
name: ''
constructor: (options) ->
self = @
self.set 'name', options.name
set: (key, val) ->
self[key] = val
get: (key) ->
return self[key]
- 10.1 Use the literal syntax for array creation.
persons = []
- 10.2 Use Array#push instead of direct assignment to add items to an array.
persons = []
person =
name: 'John Doe'
persons.push person
- 10.3 Use
slice
to copy arrays.
numbers = [4, 2]
numbersCopy = numbers.slice()
- 11.1 Use single quotes
''
for strings.
name = 'John Doe'
- 11.2 Strings, whose length exceeds the maximum amount of characters per line and would extend beyond the Right Margin (100 characters), should be split up and written across multiple lines using string concatenation.
description = 'I'm a very long text and need to be written across multiple lines using string ' +
'concatenation.'
- 11.3 Note: If overused, long strings with concatenation could impact performance. jsPerf & Discussion.
- 12.1 Never declare a function in a non-function block (if, while, etc). Assign the function to a variable instead. Browsers will allow you to do it, but they all interpret it differently, which is bad news bears.
# Don't do this!
if isTrue
createPerson = ->
return
- 13.1 When attaching data payloads to events (whether DOM events or something more proprietary like Backbone events), pass a hash instead of a raw value. This allows a subsequent contributor to add more data to the event payload without finding and updating every handler for the event.
$(this).trigger 'productBought',
productId: 42
$(this).on 'productBought', (e, data) ->
productId = data.productId
- 14.1 Don't use iterators. Prefer JavaScript's higher-order functions like map() and reduce() instead of loops like for-of.
numbers = [4, 2]
numbers.forEach (num) ->
console.log num
- 14.2 Note: Have browser compatibility in mind. (
.map
and.reduce
are not supported on <= IE8)
- 15.1 Use
String
for strings.
stringValue = String 42
- 15.2 Use
parseInt
for Numbers and always with a radix for type casting.
intValue = parseInt '42', 11
- 15.3 Use
Boolean
for booleans.
isTrue = Boolean 0
-
16.1 Use
is
andisnt
over===
and!==
. -
16.2 Note: Conditional statements such as the if statement evaluate their expression using coercion with the ToBoolean abstract method and always follow these simple rules:
- Objects evaluate to true
- Undefined evaluates to false
- Null evaluates to false
- Booleans evaluate to the value of the boolean
- Numbers evaluate to false if +0, -0, or NaN, otherwise true
- Strings evaluate to false if an empty string '', otherwise true
if [0] # true # An array is an object, objects evaluate to true return
-
16.3 Use shortcuts.
-
16.4 Note: For more information see Truth Equality and JavaScript by Angus Croll.
- 17.1 Use ###* ... ### for multi-line comments. Include a description, specify types and values for all parameters and return values.
###*
* Create a new person.
*
* @since 1.0.0
* @param {string} name
* @return {Person}
###
createPerson = (name) ->
return new Person
name: name
# FIXME: Something is wrong here, please fix it
- 17.4 Use
# TODO:
to annotate solutions to problems.
# TODO: Write more code!
- 18.1 Cache jQuery lookups.
setSidebar = ->
sidebar = $('.sidebar')
sidebar.hide()
sidebar.show()