Have a cup of CoffeeScript
CoffeeScript is a little language that compiles into JavaScript.
Setup
$ npm install -g coffee-script
Command Line Usage
# REPL
$ coffee
# Run and compile
$ coffee -o javascripts/ -c coffeescripts/
# With watcher
$ coffee -w -o javascripts/ -c coffeescripts/
# Join files
$ coffee -j javascripts/app.js -c coffeescripts/*.coffee
Vim Plugin
- kchmck/vim-coffee-script: Adds CoffeeScript support to Vim. It covers syntax, indenting, compiling, and more.
- scrooloose/syntastic: Ultimate syntax checking plugin on Vim
# shows the compiled CoffeeScript
:CoffeeCompile [vert]
# live preview compiling
:CoffeeWatch [vert]
# compiles and runs the resulting JavaScript
:CoffeeRun
Syntax
String
full_name = "#{first_name} #{last_name}"
# multiline strings are also allowed, without having to prefix each line with a +:
message = "
Hello Sir,
Great to meet you.
"
# => message = " Hello Sir, Great to meet you.";
message = """
Hello Sir,
Great to meet you.
"""
# => message = "Hello Sir,\nGreat to meet you.";
Functions
two = -> 2 + 2
# two() => 4
plus = (a, b = 1) ->
a + b
# plus(1) => 3
sum = (i...) ->
i.reduce (sum, k) -> sum + k
# sum(1, 2, 3) => 6
Using the fat arrow =>
instead of the thin arrow ensures that
the function context will be bound to the local one.
Objects
obj =
one: 1
two: 2
Conditions
r = if friday then a else b
# => friday ? a : b
Slicing and splicing
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
start = numbers[0..2]
# => start = numbers.slice(0, 3);
middle = numbers[3...6]
# => middle = numbers.slice(3, 6);
numbers[3..6] = [-3, -4, -5, -6]
# => [].splice.apply(numbers, [3, 4].concat(_ref = [-3, -4, -5, -6])), _ref;
Existential Operator
solipsism = true if mind? and not world?
# => if (typeof mind !== "undefined" && mind !== null) ...
speed ?= 15
# => if (speed == null) ...
footprints = yeti ? "bear"
# => footprints = typeof yeti !== "undefined" && yeti !== null ? yeti : "bear";
zip = lottery.drawWinner?().address?.zipcode
# => zip = typeof lottery.drawWinner === "function" ...
Comprehensions
for name in ["Roger", "Roderick", "Brian"]
alert "Release #{name}"
for name, i in ["Roger the pickpocket", "Roderick the robber"]
alert "#{i} - Release #{name}"
names = sam: seaborn, donna: moss
alert("#{first} #{last}") for first, last of names
Classes, Inheritance, and Super
class Animal
constructor: (@name, size) ->
# set property (@name) directly in constructor args
# or manually like @size
@size = size
move: (meters) ->
alert @name + " moved #{meters}m."
class Snake extends Animal
move: ->
alert "Slithering..."
super 5
class Horse extends Animal
move: ->
alert "Galloping..."
super 45
sam = new Snake "Sammy the Python"
tom = new Horse "Tommy the Palomino"
sam.move()
tom.move()
# Access an object's prototype
String::dasherize = ->
this.replace /_/g, "-"
Destructuring Assignment
weatherReport = (location) ->
# Make an Ajax request to fetch the weather...
[location, 72, "Mostly Sunny"]
[city, temp, forecast] = weatherReport "Berkeley, CA"