CoffeeScript ⇒ JavaScript
- Arrows, not
function:
- e.g.
->,(a) ->,(a,b) ->,curried = (a) -> (b) -> ··· =>bindsthisfrom outer scope- generator function if body contains
yield
- Indentation, not
{···}:
- both for code blocks, and (optionally) for
key: valueobject 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
doto 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⇒!xkey of object⇒key in objectvalue 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.kelseundefined(“null soaking”)x ? y⇒ ifx?thenxelsey(cf.x or y)x ?= v⇒ ifx?thenxelsex = v(cf.x or= v)
- Loops:
loop⇒while (true) {···}while cond⇒while (cond) {···}(negate:until)for value in array,for value, index in arrayfor 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+xto eachxiny
- Constructors:
- block expression
class C⇒ IIFE that returns a constructorC - at class-body scope level:
constructor: ->definesC(as function statement, hoisted)@/thisreferencesCname: methodadds 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