CoffeeScript ⇒ JavaScript
- Arrows, not
function
:
- e.g.
->
,(a) ->
,(a,b) ->
,curried = (a) -> (b) -> ···
=>
bindsthis
from outer scope- generator function if body contains
yield
- Indentation, not
{···}
:
- both for code blocks, and (optionally) for
key: value
object literals - inside multiline object/array literals, end-line comma delimiters are optional
- Expressions, not statements:
- expression bodies evaluate to the value of their tail-position term
- e.g. “implicit return” in function body:
ask = -> 42
- e.g. “implicit return” in function body:
- comprehensions evaluate to an array of each iteration’s evaluation
- Assignment, not declaration:
- no
var
; identifier scope determined by first/outermost assignment - use
do
to scope arbitrarily with params of IIFE, e.g.:v = do (a, b=x) -> ···
⇒v = (function(a, b) {···})(a, x)
- Operators:
- All the unary and binary operators of JS, except
void
, plus:- [
@
,C::
] ⇒ [this(.)
,C.prototype(.)
] not x
⇒!x
key of object
⇒key in object
value in array
⇒array.indexOf(value) >= 0
- [
is
,isnt
,and
,or
] ⇒ [===
,!==
,&&
,||
] x or= 42
⇒x || (x = 42)
(likewise:||=
,and=
,&&=
)- existential operator
?
(see below)
- [
- Ternary conditional replaced by expression form of
if
–then
–else
- Conditionals:
if
–then
–else if
–else
(negate:unless
)- Expression: e.g.
v = if x then y else z
⇒v = x ? y : z
- Postfix: e.g.
x if y
⇒if (y) {x}
- Existence:
x?
⇒x != null
(also catches undeclaredx
)x?.k
⇒ ifx?
thenx.k
elseundefined
(“null soaking”)x ? y
⇒ ifx?
thenx
elsey
(cf.x or y
)x ?= v
⇒ ifx?
thenx
elsex = v
(cf.x or= v
)
- Loops:
loop
⇒while (true) {···}
while cond
⇒while (cond) {···}
(negate:until
)for value in array
,for value, index in array
for key of object
,for key, value of object
,for own key ···
- optional filter clause:
for ··· when c
⇒for ··· { if (c) {···} }
- inline body with
then
, e.g.:for v in a then do (v) -> ···
- Comprehensions:
- e.g.
a = (x+x for x in y)
⇒ array mappingx+x
to eachx
iny
- Constructors:
- block expression
class C
⇒ IIFE that returns a constructorC
- at class-body scope level:
constructor: ->
definesC
(as function statement, hoisted)@
/this
referencesC
name: method
adds to prototype ofC
(equal to@::name = method
)
- Invocation (optional):
- Inline whitespace as implicit invocation paren
(
, e.g.:f a, b
⇒f(a, b)
fs = require 'fs'
data = JSON.parse fs.readFileSync 'data.json', 'utf8'
- right-associative; implicit matching
)
runs to end of clause, e.g.:f a + g b
⇒f(a + g(b))
a + f g b
⇒a + f(g(b))
f g b, c if a
⇒if (a) { f(g(b, c)) }
if f a then g b else c
⇒f(a) ? g(b) : c