9 Aug
2011

Exploring CoffeeScript Part 6 – Show Me the Goodies !

Category:UncategorizedTag: :

For the final blog post in this series, we?re going to go over a couple of cool little nuggets that one can use to write some elegant CoffeeScript code.

Also check out the previous installments:

  1. And Then There Was Coffee
  2. Variables and Functions
  3. More on Functions
  4. Objects and Classes
  5. Ranges, Loops and Comprehensions

Destructuring Assignments

Destructuring assignments are a great syntactic enhancement for those cases where we want to extract (deeply) nested property values from arrays or objects and store these values into variables.

First let?s have a look at a simple code example written in plain JavaScript where we simply assign some property values of an object to a couple of variables.

var podcast = {
    title: 'Astronomy Cast',
    description: 'A fact-based journey through the galaxy.',
    details: {
        homepage: 'http://www.astronomycast.com',
        rss: "http://www.astronomycast.com/feed/",
        atom: "http://www.astronomycast.com/feed/atom/"    
    }
};

var title = podcast.title;
var description = podcast.description;
var homepage = podcast.details.homepage;

console.log(title);
console.log(description);
console.log(homepage);

Using destructuring assignments in CoffeeScript, we can assign the property values of the object to the variables using a single line of code.

podcast =
    title: 'Astronomy Cast'
    description: 'A fact-based journey through the galaxy.'
    details:
        homepage: 'http://www.astronomycast.com'
        rss: 'http://www.astronomycast.com/feed/'
        atom: 'http://www.astronomycast.com/feed/atom/'

{title, description, details: { homepage } } = podcast

console.log title
console.log description
console.log homepage

Besides objects, destructuring assignments also works for arrays as well.

favoritePodcasts = ['Astronomy Cast', 'Hardcore History', 
                    'Talking Shop Down Under', 'The Changelog', 'Pluralcast'];
[favorite01, favorite02, favorite03, favorite04, favorite05] = favoritePodcasts

console.log favorite01
console.log favorite02
console.log favorite03
console.log favorite04
console.log favorite05

And of course, this can also be used when combine objects with arrays and vice versa.

customer =
    firstName: 'Chuck'
    lastName: 'Norris'
    orders: [
        { 
            Id: 1 
            Item: 'Knuckle Duster'
        },
        { 
            Id: 2
            Item: 'Shuriken' 
        }
    ]

{orders: [ {Item: item1}, {Item: item2}]} = customer

console.log item1
console.log item2

This small little language nugget has definitely come in handy quite more often than I first anticipated. So do keep the availability of destructuring assignments in the back of your head while developing CoffeeScript code.

String Interpolation

The syntax for string interpolation is heavily inspired on the Ruby syntax. Let?s have a look.

podcast = 
    title: 'Astronomy Cast'
    download: (episode) ->
        console.log "Downloading #{episode} of #{@title}."

podcast.download 'the first episode'

In this example we fill in the values of the episode parameter and the title property into the string that we send to the console.log method. Unfortunately string interpolation only works for double quoted strings. I personally prefer single-quoted strings when I?m writing CoffeeScript code. But I gladly make an exception when I want to use string interpolation.

Strict Equality

In JavaScript, we have the == and the === operator. Both equality operators behave the same way only the first performs type coercion while the latter enforces type equality. It’s a common best practice in JavaScript to always use the strict equality operator and explicitly perform type casts if needed. CoffeeScript on the other hand only has only one equality operator which always translates to JavaScript’s strict equality operator behind the scenes.

So the following equality comparison written in CoffeeScript translates to the JavaScript code shown bellow:

# CoffeeScript
x = 'str'
y = 12
console.log x == y        # Outputs 'false'


// JavaScript
var x, y;
x = 'str';
y = 12;
console.log(x === y);

As I already mentioned in one of the previous blog posts, CoffeeScript emits JavaScript that follows best practices and complies to JSLint without warnings. Always using the === operator is part of being compliant.

Conditionals

CoffeeScript adds some nicely readable syntactic sugar to be used with conditionals using keywords like unless, is, isnt, and and or. Let?s look at an example.

cobol = vb = false
cool = true

unless cobol is cool
    console.log 'CoffeeScript is awesome!'

if vb isnt cool
    console.log 'CoffeeScript is awesome!'

if cobol isnt cool and vb isnt cool
    console.log 'CoffeeScript is awesome!'

I really like how these keywords enable us to write fluently readable conditional statements in CoffeeScript.

The Existential Operator

The existential operator in CoffeeScript, expressed using the ? symbol, returns true except when a particular variable is null or undefined. Let?s look at some code.

someVariable = null
someOtherVariable = 12

console.log someVariable ? someOtherVariable        # Outputs 12

unless someVariable?
    console.log 'someVariable is null'

But the existential operator can also be used to check for null or undefined before accessing a property or the result of a function. This is also called a soak which is the accessor variant of the existential operator. Again some code to clarify things.

podcast =
    title: 'Astronomy Cast'
    description: 'A fact-based journey through the galaxy.'
    details:
        homepage: 'http://www.astronomycast.com'
        rss: 'http://www.astronomycast.com/feed/'
        atom: 'http://www.astronomycast.com/feed/atom/'

    download: -> null

# Outputs 'http://www.astronomycast.com'
console.log podcast.details.homepage    

# TypeError: Cannot read property 'publishingDate' of undefined            
console.log podcast.moreDetails.publishingDate        

# Outputs undefined
console.log podcast.moreDetails?.publishingDate     

# Also outputs undefined
console.log podcast.download()?.data

When the property in question has a valid value, then the expected result is returned. In case the property does not exist or contains null, then undefined is returned instead of a TypeError being thrown.

So that?s it for now. I hope that you enjoyed reading this blog series on CoffeeScript and perhaps you are now also convinced that using CoffeeScript is a viable and productive alternative for writing JavaScript based applications.

Until next time.