Site icon Treehouse Blog

The Absolute Beginner’s Guide to CoffeeScript

CoffeeScript has become increasingly popular over the last couple of years due to its adoption by the Node.js and Rails communities. Let’s take a look why it’s become the go-to language when people are wanting to write JavaScript in their apps.

What is CoffeeScript?

CoffeeScript is a language that gets compiled to JavaScript. Code in .coffee files are not interpreted at run time, like JavaScript, but are compiled into .js files.

Whether you’re writing for JavaScript for the Node.js or any given browser’s implementation, CoffeeScript can be written for any and all flavors of JavaScript.

Why CoffeeScript?

In the past, JavaScript hasn’t had the most stellar of reputations due to the copy-and-paste mentality of the 90’s and early 2000’s, it seemed that only a few had any idea what was going on. It was looked down on as a not so “serious” language. However, JavaScript as a language has a lot to offer and has some super features.

CoffeeScript makes use of the powerful features of JavaScript without learning the less known features of JavaScript by adding “syntactic sugar” to JavaScript. CoffeeScript doesn’t have the semi-colons and curly braces, similar syntax to the likes of Python and Ruby.

This means you can write less code and do things faster. It also makes it easier to read and maintain.

Due to optimizations CoffeeScript uses, when it’s compiled down, the resulting JavaScript is just as performant or in some instances it’s even more performant over hand-written code.

You can learn a lot about JavaScript by looking at the JavaScript that CoffeeScript compiles down to. If there’s something new that you see there, research it and see why CoffeScript compiles that way rather than what you’re used to seeing.

Installing CoffeeScript

Let’s install CoffeeScript so you can follow along. CoffeeScript is a Node.js package. So it depends on Node.js and the package manager (npm).

On OS X

Node.js can be installed using Homebrew, an open source Package Manager for OS X. You can review the installation process of Homebrew here.

Make sure you’re Homebrew is up to date by typing brew update in your terminal.

The Homebrew formula for Node.js is node. So to install Node.js you type in brew install node into your terminal. Follow any additional instructions that appear if you need to alter PATHs or anything like that.

Then type npm install -g coffee-script to install it globally.

On Windows

Visit Node.js’ website and press the “Install” button. It should auto-detect your flavor of Windows you’re using and an installer will start to download.

Go through the install process.

Once it’s installed open up your Command Prompt and type npm install -g coffee-script to install it globally.

And finally

Type coffee -v in your command line to see it’s been installed correctly.

Command Line Usage

The coffee compiler can be used in several ways. Here’s a couple to see what’s available.

Run and Compile

The following command will compile all your .coffee files in a folder called coffeescripts to .js files in a parallel tree structure in the javascripts folder.


coffee -o javascripts/ -c coffeescripts/

Warning

The option -c means to compile and -o means the output folder. Note the ordering is output then compile. This is because if you switch the order it doesn’t work!

Watcher

Running the above command every time you want to compile CoffeeScript files so there’s another handy option to use, -w.


coffee -w -o javascripts/ -c coffeescripts/

The watcher listens to changes to the files in the coffeescripts folder and compiles them on the fly.

If you add a new file to the coffeescripts folder should compile, however if you add a new folder and a CoffeeScript file inside that it won’t be compiled. This could change in later versions.

Joining Files

You can also compile all your .coffee files down to a single JavaScript file. This will reduce the number of HTTP request a browser has to make and improve performance. To do this use the -j option like so:


coffee -j javascripts/app.js -c coffeescripts/*.coffee

The * is a wildcard operator.

REPL

If you type coffee without any options an interactive shell opens. This is similar to irb in Ruby. This is a great tool for things out in the console and performing quick experiments.

Text Editor Highlighting

If you’re going to code in CoffeeScript the best thing to do is have syntax highlighting.

TextMate

Jeremy Ashkenas, CoffeeScript’s inventor, created a handy TextMate bundle. For installation instructions go here.

Sublime Text 2

Sublime Text 2 has a plugin created by GitHub user Xavura. You can install this via the Sublime Package Control, if you have that already.

The Good Stuff a.k.a. The Syntax

Variables

Variables in CoffeeScript don’t require the keyword var. Simply name your variable, an equals sign, and then the value.


year = 1985
speed = 88

Strings

Strings are declared with quotes like in most other languages.


first_name = "Marty"

To join or concatenate strings, you can list them one after another with a plus symbol in between, like this:


full_name = first_name + " McFly"

You can also include the hash symbol (#), followed by curly braces, and within those the string variable.


full_name = "#{first_name} McFly"

The above two examples would create the string Marty McFly.

The latter type of string interpolation only works when you use double quotes. If you use single-quotes the text is displayed “as is”. Single quote strings are literal strings.


full_name = '#{first_name} McFly'

So the above will be the string of #{first_name} McFly. This mirrors behavior.

Functions

Functions are declared by naming the function, equals sign, and then a special function symbol (->).


initialize_time_circuits = -> year * flux_capacitor_constant * speed

We haven’t used the keyword return because every function in CoffeeScript returns the result of the last line of code.

Multi-lined functions are writen on multiple lines with each line after the declaration having some white space before it.


initialize_time_circuits = -> 
  year = 1885
  year * flux_capacitor_constant * speed

This would set the year to 1885 every time. If we want the year to be a lot more flexible but have a default we can bring it up into the method declaraion like this:


initialize_time_circuits = (speed, year = 1885) -> 
  year * flux_capacitor_constant * speed

This will mean we can then call this with one value of the speed the year will always default to 1885.


    initialize_time_circuits(88)

You can also call methods without using parentheses. The above can also be written like:


    initialize_time_circuits 88

Arrays

There are several different ways to initialize and declare arrays in CoffeeScript. You’re probably used to seeing arrays declared with square brackets and values separated by commas.


    mcflys = ["Marty", "George", "Lorraine", "Dave", "Linda"]

You can also declare arrays over multiple lines like this:


  mcflys = [
   "Marty", 
   "George", 
   "Lorraine", 
   "Dave",
   "Linda"
  ]

You have to have white space on each line.

Optionally, you can remove the trailing comma from each line.


  mcflys = [
   "Marty" 
   "George"
   "Lorraine" 
   "Dave"
   "Linda"
  ]

You can also use a combination of these two declaration styles.

The following example…


woah = [
  0, 1, 9
  6, 5, 4
  8, 0, 0
]

…is the equivalent to:


woah = [0, 1, 9, 6, 5, 4, 8, 0, 0]

Which may be more or less legible depending on your application. CoffeeScript allows you to do it in a variety of ways to suit your needs.

Objects

Object literals or hashes can be declared like their JavaScript counterparts and in some other funky ways.

Given the following JSON…


teachers = {
  teacher: {
    name: "Andrew Chalkley", 
    hair: "Ginger"
  }, 
  teacher: {
    name:"Jim Hoskins",
    hair: "Ginger"
  },
  teacher: { 
    name:"Pasan Premaratne",
    hair: "Black"
  }
}

…you can drop the commas and curly braces:


teachers =
  teacher:
    name: "Andrew Chalkley"
    hair: "Ginger"
  teacher:
    name: "Jim Hoskins"
    hair: "Ginger"
  teacher:
    name: "Pasan Premaratne"
    hair: "Black"

As long as you indent with some white space, the structure gets nested as you’d expect.

Ranges

Ranges are declared by two integer separated by two periods, wrapped in square brackets.


days = [1..7]

Ranges aren’t a standard object type in Javascript so they get compiled down to arrays.

To get a sub-section of an array you can pass in a range too. Want to get days from tuesday_to_friday where Monday is 1 and Sunday is 7? Since arrays are indexed zero-based, we’d start at 1 and end at 4.


days = [1..7]

tuesday_to_friday = days[1..4]

You can replace whole sections of arrays in a similar way too.

The following…


days[1..4] = ["Tuesday", "Wednesday","Thursday", "Friday"]

Modifies the days array to be [ 1, 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 6, 7 ].

You can use ranges to countdown too for example [10..0] would be 10 to 0.

Splat

A splat is a convenient way to accept multiple values as arguments to methods.

In the following example we want to award kudos points to a group of forum users for the number of posts in a given week.

The first person gets 10 points, the second gets 6, the third gets 2 and every one else will get a single point.

Let’s create a function, giveKudos With first, second, and third as parameters. For the rest well use a splat, which is the name of the variable followed by 3 periods. Within the giveKudos method let’s call an unimplemented addKudosToUser which takes two parameters, the user and the points to be added. We’re not going to worry about the implementation it’s just for illustrative purposes.


giveKudos = (first, second, third, rest...) ->
  addKudosToUser first, 10
  addKudosToUser second, 6
  addKudosToUser third, 2

Next we can use a for in to loop over the rest.


giveKudos = (first, second, third, rest...) ->
  addKudosToUser first, 10
  addKudosToUser second, 6
  addKudosToUser third, 2
    for user in rest
      addKudosToUser user, 1

Given we have an array of users:


users = ["Pasan", "Amit", "Jim", "Andrew", "Allison", "Jason", "A.J."]

We want Pasan to get 10 points, Amit to get 6, Jim to get 2 and then the rest to get 1.

We need to pass in users with the periods in to the method to properly assign the array values to the parameters like this:


giveKudos users...

Without these periods, users get’s assigned to the first parameter and undefined to the rest.

Classes

Classes can be declared trivially in CoffeeScript which is a refreshing contrast to the much more verbose JavaScript.

First write the keyword class, followed by the name of your class.

Methods, including the constructor method, are written with the name of the method followed by a colon. White space is needed before each method name. You can then use the function operator (->).


class TimeMachine
  constructor: ->

To instantiate an instance of an object, use the keyword new followed by the class name.


time_machine = new TimeMachine

Instance Variables

Instance variables start with an @ symbol. So we can have a pilot


class TimeMachine
  constructor: (pilot) ->
    @pilot = pilot

You can access them via dot notation too.


class TimeMachine
  constructor: (pilot) ->
    @pilot = pilot
    
    
time_machine = new TimeMachine "H. G. Wells"

console.log time_machine.pilot

In the above example the string H. G. Wells would be printed to the console.

Instead of setting @pilot = pilot you can write it in shorthand like this:


class TimeMachine
  constructor: (@pilot) ->

Class Inheritance

To write a subclass you can use extends like this:


class Tardis extends TimeMachine

class DeLorean extends TimeMachine

Let’s say TimeMachine has a method go with one parameter that gets logged out when the Time Machine is about to travel in time.


class TimeMachine
  constructor: (@pilot) ->
  go: (noise) ->
    console.log noise

Now let’s for each time machine implement go and call the super method.


class Tardis extends TimeMachine
  go: ->
    super "vorp vorp"
    
class DeLorean extends TimeMachine
  go: ->
    super "One point twenty-one gigawatts!"
    
doctors_wife = new Tardis "The Doctor"
doc_browns_wheels = new DeLorean "Marty"

doctors_wife.go()
doc_browns_wheels.go()

So calling go() on instances of both time machines will print out it’s own respective sound.

General Syntax

With CoffeeScript you’ll find your code looking more like a sentence in English:


light_bulbs() if switch is on

Which is the same as:


light_bulbs() unless switch is not on

While the latter is harder to parse than the former, it does show you the scope of the new sugar.

Here’s a table of equivalents from the CoffeeScript documentation page on Operators and Aliases.

CoffeeScript JavaScript
is ===
isnt !==
not !
and &&
or ||
true, yes, on true
false, no, off false
@, this this
of in
in no JS equivalent

Existential Operator

CoffeeScript brings another cool operator to the table called the Existential Operator, which is a question mark (?).

Let’s say if a user hasn’t signed in and been set yet. You want the login function to be called if the user isn’t present, then just use the Existential Operator like so:


login() if not user?

You can also set default values like so:


year ?= 1885

You can use the Existential Operator in a similar way to a ternary operator. The following example would set greeting to be either message, if not undefined or the string `”Hello, World!”.


greeting = message ? "Hello, World!"

Finally there’s an accessor variant which you can use absorb up null references when you’re chaining properties together.


ip = securitySystem.lastUser?().remoteSystem?.ipAddress

So instead of raising a TypeError this would return undefined.

Comprehensions

Comprehensions can make your code more readable. In our kudos example we had the for loop going over two lines, when we could have written it on one line like this:


giveKudos = (first, second, third, rest...) ->
  addKudosToUser first, 10
  addKudosToUser second, 6
  addKudosToUser third, 2
    addKudosToUser user, 1 for user in rest

Another cool feature of looping over things in CoffeeScript is that the loop returns an array of the results of that loop. Let’s say I want to count from 0 to 100 in multiples of 10. All I do is prepend my loop with a variable assignment like so:


multiples = for num in [0..10]
                     num * 10

Adding parentheses you can bring it on to one line too!


multiples = (num * 10 for num in [0..10])

Conclusion

Woah! That was a lot to take in but as you can see CoffeeScript is full of tasty sugary syntax. Why not give it a bash in your next JavaScript project and see what it compiles down to under the hood?

Exit mobile version