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,
_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
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
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
So what does
void 0 do now?
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
(the parens are optional, hence the
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
undefined. This is because the
undefined types are equal (
==), but not strictly equal (
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 🙂