Introducing CoffeeScript

  • Tutorial
The article is not an exhaustive description of the CoffeeScript programming language, namely an acquaintance, an overview of some interesting features. The target audience is those who have not yet looked towards CoffeeScript, but one way or another use JavaScript in their projects.

CoffeeScript is a small language that translates into JavaScript. Its documentation fits on one page - and is compact and clear. I even doubted the necessity of this article when there is such a cool description “from the manufacturer”, but still I ventured to put emphasis and clarify some details.


If you dig a bit of history, then since 2009, the language has been written in Ruby, since 2010 - it is written in CoffeeScript itself.
And in Ruby on Rails, starting with version 3.1, it "replaced" JavaScript.

Essentially, CoffeeScript is just syntactic sugar over JavaScript. So, its value is that it allows you to more clearly express your thoughts and understand others.

JavaScript (read ECMAScript), of course, also does not stand still, it is developing. Including adopting some ideas from CoffeeScript. But speaking of cross-browser JavaScript, I personally have great suspicions that a bright future with advanced JavaScript will come soon. And CoffeeScript now allows you to enjoy the fruits of technological progress.

In this vein, one cannot but mention TypeScript, in a certain sense, a competitor to CoffeeScript. It is positioned as a superset of JavaScript, adding new features to the language, largely reflecting the future of JavaScript. From this position he is more interesting.
But CoffeeScript has the advantage that it does not need to maintain compatibility with JavaScript, which, in my opinion, gives more freedom and allows you to make the language more expressive. So, there is at least one noteworthy CoffeeScript alternative. But back to the topic.

Code translation

Ok, how to use this with your CoffeeScript?
In my opinion, it is most convenient to work with it as with the node.js. module. It is put as simple as
npm install -g coffee-script

possible : We create two folders, for definiteness we will name them liband src.
Create a file src/helloWorld.coffeeand write something on CoffeeScript. For instance:
console.log('Hello world')

After that, run the translator:
coffee --compile --output lib/ src/
As a result, the file libwill be in the folder helloWorld.js, ready for execution.
Of course, it’s not interesting to run a translator for everyone. Running the command
coffee -o lib/ -cw src/
forces you to monitor all changes to the files in the folder srcand independently translate them into JavaScript code.



Let's move on to the language itself. Let's write a simple CoffeeScript code:
square = (x) -> x * x
cube   = (x) -> square(x) * x

Its JavaScript equivalent:
(function() {
var cube, square;
square = function(x) {
  return x * x;
cube = function(x) {
  return square(x) * x;

Here we create two functions that calculate the square and cube of a number, respectively.

First of all, note that all the code is hidden inside an anonymous function that we immediately call.
This technique allows you to hide all local variables inside the function, without worrying that they will clog the global scope. Below in the article we will omit this function for clarity.

Next, note that the declaration of all local variables is var cube, squareplaced at the beginning. Which protects against a common mistake when a variable for no reason, for no reason has become global because of the banal forget to add an ad var.

The arrow ->replaces the word function.
And also note that there is no need to add a wordreturn. It is added automatically to the last expression in the function.

Default Parameter Values

CoffeeScript adds default values ​​for function parameters, which is not available in JavaScript.

CoffeeScript example:
fill = (container, liquid = "coffee") ->
  "Filling the #{container} with #{liquid}..."

JavaScript equivalent:
var fill;
fill = function(container, liquid) {
  if (liquid == null) {
    liquid = "coffee";
  return "Filling the " + container + " with " + liquid + "...";

The JavaScript implementation boils down to checking the parameter liquidfor equality nullor undefined.
Another detail that the example illustrates is that indentation of blocks is not using curly braces, but indents, as in Python.

Iterate over object properties

Another thing that annoys in JavaScript is a very verbose iteration over the properties of objects.
The fact is that in most cases when walking around an object, its own properties are of interest, not the properties of the prototype.
And to do it every time forand in it immediately the check is a hasOwnPropertylittle tiring.
The solution in the style of jQuery.each () was not forbidden by anyone, but it is inferior in effectiveness to the old-fashioned one for.

We look how to make it cool:
yearsOld = max: 10, ida: 9, tim: 11
for own child, age of yearsOld
  console.log "#{child} is #{age}"  

var age, child,
  __hasProp = {}.hasOwnProperty;
for (child in yearsOld) {
  if (!, child)) continue;
  age = yearsOld[child];
  console.log("" + child + " is " + age);

Pleasant trifles

In JavaScript, the == operator behaves mildly strange. It is much safer to use ===. Therefore, CoffeeScript converts the == operator to ===, protecting novice developers from traps in JavaScript. Although one case comes to mind when the == operator is still useful. This comparison with nullthat allows you to check nulland undefinedin one fell swoop. In CoffeeScript, the operator is for this purpose ?. Consider an example:
alert "I knew it!" if elvis?

And at the output:
if (typeof elvis !== "undefined" && elvis !== null) {
  alert("I knew it!");


We pass to classes. Just in case, we clarify that we will call classes constructor functions of objects.

Consider an example:
class Animal
  constructor: (@name) ->
  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"

Even intuitively, you can guess what is happening. The base class Animaland its two heirs are described : Snakeand Horse.
Let's pay attention to the class Animal. The entry @namein the constructor parameters is a convenient abbreviation that defines the property of the name class and automatically assigns the value passed to it in the constructor. In the move method, the entry @nameis short for

In methods movein subclasses, it supercalls the parent method of the same name. After all, the truth is, when we are in a child class, a reference to the parent is sometimes needed only to refer to the parent class method of the same name. Other cases do not even occur.

I will not languish and, finally, we will move on to the js-version of our classes.
var Animal, Horse, Snake, sam, tom, _ref, _ref1,
  __hasProp = {}.hasOwnProperty,
  __extends = function(child, parent) { for (var key in parent) { if (, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
Animal = (function() {
  function Animal(name) { = name;
  Animal.prototype.move = function(meters) {
    return alert( + (" moved " + meters + "m."));
  return Animal;
Snake = (function(_super) {
  __extends(Snake, _super);
  function Snake() {
    _ref = Snake.__super__.constructor.apply(this, arguments);
    return _ref;
  Snake.prototype.move = function() {
    return, 5);
  return Snake;
Horse = (function(_super) {
  __extends(Horse, _super);
  function Horse() {
    _ref1 = Horse.__super__.constructor.apply(this, arguments);
    return _ref1;
  Horse.prototype.move = function() {
    return, 45);
  return Horse;
sam = new Snake("Sammy the Python");
tom = new Horse("Tommy the Palomino");

Inheritance is based on a variation of the classical function extend.
The implementation is quite simple. Of course, when compared with other JavaScript libraries that provide a convenient cross-browser implementation of classes in pure JavaScript.
The downside of fancy libraries is that it's not always easy to figure out how they work inside.
And the function is extendvery well described in many sources, for example, here .


Another important criterion is the efficiency of the generated code. So, with this everything is in order, I did not find any nonsense. Functions as expected are not added as class properties, but to the prototype. I was also pleased that the default value of class properties is also added to the prototype.

Consider a very simple class:
class Foo
  bar: 10

The output is JavaScript:
var Foo;
Foo = (function() {
	function Foo() {} = 10;
	return Foo;

Here, the so-called asymmetry of the object's properties for reading and writing is used.
In real life, the default property value is almost always more profitable to add to the object prototype.
Until we need to change this default value, we do not waste extra memory for each object of a certain class. But let's say we decided to change the value of this property like this:
obj = new Foo() = 500

This creates a personal property of barthe object obj. In this case, the property of the barprototype object objis still equal to 10. Everything is safe and effective.

The only thing that can be confusing in this approach is that when accessing the property that is in the prototype, you have to move along the prototype chain. And this is not given for free. But on modern engines this is not essential, especially against the background of radical optimization of memory usage, but old IEs, in which degradation was felt, are gradually disappearing into oblivion.

Assigning Event Handlers

Another cool feature is the appointment of event handlers for object methods. Example:
Account = (customer, cart) ->
  @customer = customer
  @cart = cart
  $('.shopping_cart').bind 'click', (event) =>
    @customer.purchase @cart

var Account;
Account = function(customer, cart) {
  var _this = this;
  this.customer = customer;
  this.cart = cart;
  return $('.shopping_cart').bind('click', function(event) {
    return _this.customer.purchase(_this.cart);

In order to specify the method of the same object in pure JavaScript as an event handler, you have to get out.
One of the most common ways is to create a closure. In CoffeeScript, this crutch is not needed. It is enough to indicate the function of the handler not as ->, but =>. After that, the thishandler will refer to the base object.

Pure JavaScript Integration

If you need to connect pure JavaScript code, then this is also easy to do:
hi = `function() {
  return [document.title, "Hello JavaScript"].join(": ");

The output is:
var hi;
hi = function() {
  return [document.title, "Hello JavaScript"].join(": ");


And of course, there are many chips for working with arrays and objects. To illustrate, consider one.
For example, suppose we want to get an array of cubes of numbers from 1 to 5.

In CoffeeScript, just write:
cubes = (Math.pow(num, 3) for num in [1..5]) 

In verbose JavaScript, we get:
var cubes, num;
cubes = (function() {
  var _i, _results;
  _results = [];
  for (num = _i = 1; _i <= 5; num = ++_i) {
      _results.push(Math.pow(num, 3));
  return _results;


I hope for dating should be enough. Further welcome to .

Well, as expected, a few conclusions:
  • CoffeeScript increases the expressiveness of the code, simplifies and speeds up both the initial development and further support of the code.
  • The training is very fast (it took me a couple of days to get involved).
  • Convenient support from WebStorm (For other IDEs there are also plugins, but I can not say anything about their quality)
  • Big community
  • Protects especially novice developers from many mistakes.

The main thing is to understand what CoffeeScript generates. Then it turns from an extra suspicious layer of abstraction into a powerful tool.

Also popular now: