Product & IT Blog
Menu

I had been working with JavaScript for quite some time, before we decided to use CoffeeScript at Wimdu. Back then I only had a rough idea of this ‘little language’ that compiles to JavaScript. So I was neither totally in favor of nor really against it.

I’ve started to enjoy quite a few things about it since then, like the concise syntax and features like fat arrow functions for example.

I still see CoffeeScript code, whether by a colleague or on the web, and wonder what it actually compiles to. And looking under the hood can be quite insightful at times.

The other day I saw something in our code which makes use of the accessor variant of CoffeeScript’s existential operator, and it got me curious.

So, while the existential operator ? only checks for the existence of a variable, the accessor variant ?. allows you to access a property safely. That means, no error is being thrown when the property doesn’t exist.

Consider this example from coffeescript.org:

zip = lottery.drawWinner?().address?.zipcode

Which translates to:

var zip, _ref;
zip = typeof lottery.drawWinner === "function" ? (_ref = lottery.drawWinner().address) != null ? _ref.zipcode : void 0 : void 0;

When I was looking at this, the part which I didn’t get right away was the void 0. But let’s take a step back and look at what the whole piece of code does.

First it declares two variables, zip and _ref. Since only zip appears in the written code, _ref has obviously been generated by CoffeeScript for internal use behind the scenes.

To assign the correct value to zip, it initially checks if the drawWinner property of lottery is actually a function. It does so by using JavaScript’s typeof operator, which “returns a string indicating the type of the unevaluated operand”.

And instead of using a simple if statement here, CoffeeScript decided to go with the ternary operator, sometimes also referred to as the conditional operator. It’s kind of a shortcut for the if statement.

That means if drawWinner turns out to be of type `function`, the part between the ? and the first : will be returned. But if drawWinner is of a different type, then it’s gonna be the part after the first :, which is void 0.

So what does void 0 do now?

Usually, the typeof operator will return the falsy value undefined, if you give it a nonexistent operand:

typeof lottery.nonexistent //"undefined"

But it turns out that in non-ECMAScript 5 environments, of which by now Internet Explorer 8 is probably the only one you might have to be concerned about, undefined is neither a reserved word nor is it immutable. That means you could actually do the following without getting an error:

undefined = true;

This is obviously not a good idea, as it would break anything which depends on the real undefined. Even though someone overwriting it might be something unlikely to happen, you cannot be absolutely sure about it.

In comparison, the void operator evaluates whatever you give it and always returns the real undefined.

void('test') //"undefined"
void(123) //"undefined"

(the parens are optional, hence the void 0)

This means that CoffeeScript has a defensive approach and uses `void 0` as a safe and concise way to obtain the real undefined, instead of relying on the fact that undefined hasn’t been overwritten.

If we go back to the code snippet above, there is a second ternary operator nested inside the first one:

(_ref = lottery.drawWinner().address) != null ? _ref.zipcode : void 0

Here the result of lottery.drawWinner().address is being assigned to the above mentioned variable _ref, which has been created by CoffeeScript for internal use.

It is then checked if the resulting value is != null, which actually checks for null and undefined. This is because the null and undefined types are equal (==), but not strictly equal (===).

So, even from looking at what a small piece of CoffeeScript compiles to, you could possibly learn a few things about JavaScript (even if only about its quirkiness).

A more involved example are the following lines from the CoffeeScript Cookbook, which might look rather harmless initially:

mixOf = (base, mixins...) ->
  class Mixed extends base
  for mixin in mixins by -1 #earlier mixins override later ones
    for name, method of mixin::
      Mixed::[name] = method
  Mixed

But this one is for yourself to explore 🙂

About the author

Oliver Schmidt

Front-end Developer

Share this article