http://www.developer.com/lang/jscript/coffeescript-create-optimized-javascript-code-without-touching-javascript.html

Back to article

CoffeeScript: Create Optimized JavaScript Code Without Touching JavaScript


May 19, 2011

Over the course of the past 15 years, JavaScript has evolved from an annoying language used to scroll messages in the browser status bar to an annoying language responsible for powering significant parts of the Web. While libraries such as jQuery have certainly lessened the pain incurred when integrating JavaScript into a website, there remains a great deal of angst when it comes to the only language with the dubious distinction of having a book written about it that focuses only on "the good parts".

In 2009 an enterprising programmer named Jeremy Ashkenas began an attempt to remove all of the pain incurred when writing JavaScript in a most interesting way: by creating another programming language which is compiled into… JavaScript. Dubbed CoffeeScript, developers can use this heavily Ruby- and Python-influenced language to write programs which compile into succinct and highly optimized JavaScript.

Installing CoffeeScript

CoffeeScript can be installed through the Node Package Manager, a command-line Node.js package management tool. Therefore you'll need to first install Node.js and Node Package Manager (see the instructions on their respective websites for more information). Once installed, run the following command to install CoffeeScript:

$ npm install coffee-script

Once installed, make sure everything is working by invoking the coffee command with the -v option:

$ coffee -v
CoffeeScript version 1.0.1

Creating Your First CoffeeScript Program

With CoffeeScript installed, it's time to explore the language syntax and write your first program. Open up your IDE and create a new file named hello.coffee. Add the following contents to it:

hello = "1 + 1 = #{1 + 1}"
alert(hello)

This is a simple but compelling example of just one convenience CoffeeScript has to offer over JavaScript. Were you to want to intertwine dynamic data (such as a mathematical calculation) with a string, JavaScript requires you to concatenate the disparate data using a plus sign, a practice which is often error prone and ugly. In contrast, CoffeeScript allows you to embed the dynamic data into the string using the same syntax used within Ruby. Additionally, note the lack of line-ending semicolons. While you can optionally include them if you choose to do so, the lack of this requirement is just one of many Python-inspired features enjoyed by CoffeeScript users.

Now compile the hello.coffee into JavaScript using the following command:

$ coffee -c hello.coffee

A file named hello.js will be created and saved into the same directory as the hello.coffee script. Open it and you'll see the following JavaScript code:

(function() {
  var hello;
  hello = "1 + 1 = " + (1 + 1);
  alert(hello);
}).call(this);

Reference the hello.js file in an HTML file (see below) and load it into the browser. You'll be greeted with the alert box presented in Figure 1.

Creating Dynamic Output with CoffeeScript
Figure 1. Creating Dynamic Output with CoffeeScript

You're probably already wondering how to forego the additional step of having to compile the CoffeeScript file into JavaScript in order to test the code in the browser. Use the coffee command's --watch option, and the file will automatically be compiled every time it is saved:

$ coffee --watch -c hello.coffee
15:04:59 GMT-0400 (EDT) - compiled hello.coffee
15:05:16 GMT-0400 (EDT) - compiled hello.coffee

CoffeeScript Functions and Arguments

CoffeeScript offers a few great shortcuts for defining and executing functions and methods. The arrow operator (->) is used when defining a function, and is prefaced by the argument list. Further, when executing a function or method, you can forego encapsulating the arguments within parentheses. The following Google Maps API snippet demonstrates both of these features:

handler = () -> map.panTo marker.getPosition()

google.maps.event.addListener marker, 'click', handler

Once compiled, the resulting JavaScript looks like this:

handler = function() {
  return map.panTo(marker.getPosition);
};
google.maps.event.addListener(marker, 'click', handler);

Looping with Comprehensions in CoffeeScript

Another interesting CoffeeScript feature is its particular approach to looping statements. In lieu of the traditional for statement you can use what the CoffeeScript documentation refers to as a comprehension. This syntax is incredibly succinct, allowing you to loop over an array using just one line of code, as demonstrated here:

positions = [
  '38.894505, -77.025034',
  '38.904483, -77.036048',
  '38.897041, -77.023521',
  '38.894505, -77.025034'
]

alert position for position in positions

The last line forms the looping statement, declaring that alert(position) should execute once for every element (stored in position) in the positions array. Once compiled, the resulting JavaScript looks like this:

(function() {
  var position, positions, _i, _len;
  positions = ['38.894505, -77.025034', '38.904483, -77.036048', 
               '38.897041, -77.023521', '38.894505, -77.025034'];
  for (_i = 0, _len = positions.length; _i < _len; _i++) {
    position = positions[_i];
    alert(position);
  }
}).call(this);

Creating Objects in CoffeeScript

CoffeeScript borrows from YAML syntax in a manner which allows you to streamline the creation of objects. All you need to do is indent each property, as demonstrated here:

locations = 
  embassy:
    name: 'Former Soviet embassy'
    latitude: 38.904483
    longitude: -77.036048
  museum:
    name: 'International Spy Museum'
    latitude: 38.897041
    longitude: -77.023521

Compiling this snippet produces the following JavaScript object:

var locations;
  locations = {
    embassy: {
      name: 'Former Soviet embassy',
      latitude: 38.904483,
      longitude: -77.036048
    },
    museum: {
      name: 'International Spy Museum',
      latitude: 38.897041,
      longitude: -77.023521
    }
  };

Having Cake with Your Coffee

Beyond the enormous set of syntactical conveniences, CoffeeScript is even bundled with its own build system which you can use to automate a wide variety of JavaScript-related tasks. Called Cake (not to be confused with CakePHP), you can create build files which define tasks (conveniently written in CoffeeScript) for automating anything which strikes your fancy, such as executing JSLint, running JSUnit unit tests, or building documentation.

Where to From Here?

Although the project has attracted a great deal of interest, CoffeeScript is still in its infancy and learning resources are few and far between. Fortunately, the CoffeeScript documentation is incredibly well done. In particular I suggest reviewing the examples and resources section, which among other things contains links to several impressive projects implemented using CoffeeScript, among them the amazing tank game orona. Additionally, be sure to check out Jamis Buck's amazing CoffeeScript-driven mazes.

Are you currently doing anything with CoffeeScript? If so tell us about it in the comments!

About the Author

Jason Gilmore-- Contributing Editor, PHP--is the founder of EasyPHPWebsites.com, and author of the popular book, "Easy PHP Websites with the Zend Framework". Jason is a cofounder and speaker chair of CodeMash, a nonprofit organization tasked with hosting an annual namesake developer's conference, and was a member of the 2008 MySQL Conference speaker selection board.

Sitemap | Contact Us