Writing Your First Lines of CoffeeScript

Exclusive offer: get 50% off this eBook here
CoffeeScript Application Development

CoffeeScript Application Development — Save 50%

Write code that is easy to read, effortless to maintain, and even more powerful than JavaScript with this book and ebook

$26.99    $13.50
by Ian Young | August 2013 | Open Source Web Development

This article, written by Ian Young, the author of the book CoffeeScript Application Development, will dive into CoffeeScript head first. We'll look at all the simple data types and control structures, and find out how CoffeeScript helps us deal with them more simply and expressively. We'll discover some neat tricks that save us keystrokes and reduce the likelihood of errors in our code. And we'll peek under the hood to see how some of the CoffeeScript magic is happening.

In this article, you can expect to:

  • Learn CoffeeScript syntax for many common operations
  • Learn how to use standard data types and control structures in CoffeeScript
  • See how the CoffeeScript we write maps back to JavaScript once compiled

(For more resources related to this topic, see here.)

Following along with the examples

I implore you to open up a console as you read this article and try out the examples for yourself. You don't strictly have to; I'll show you any important output from the example code. However, following along will make you more comfortable with the command-line tools, give you a chance to write some CoffeeScript yourself, and most importantly, will give you an opportunity to experiment. Try changing the examples in small ways to see what happens. If you're confused about a piece of code, playing around and looking at the outcome will often help you understand what's really going on.

The easiest way to follow along is to simply open up a CoffeeScript console. Just run this from the command line to get an interactive console:

coffee

If you'd like to save all your code to return to later, or if you wish to work on something more complicated, you can create files instead and run those. Give your files the .coffee extension , and run them like this:

coffee my_sample_code.coffee

Seeing the compiled JavaScript

The golden rule of CoffeeScript, according to the CoffeeScript documentation, is:

It's just JavaScript.

This means that it is a language that compiles down to JavaScript in a simple fashion, without any complicated extra moving parts. This also means that it's easy, with a little practice, to understand how the CoffeeScript you are writing will compile into JavaScript. Your JavaScript expertise is still applicable, but you are freed from the tedious parts of the language. You should understand how the generated JavaScript will work, but you do not need to actually write the JavaScript.

To this end, we'll spend a fair amount of time, especially in this article, comparing CoffeeScript code to the compiled JavaScript results. It's like peeking behind the wizard's curtain! The new language features won't seem so intimidating once you know how they work, and you'll find you have more trust in CoffeeScript when you can check in on the code it's generating. After a while, you won't even need to check in at all.

I'll show you the corresponding JavaScript for most of the examples in this article, but if you write your own code, you may want to examine the output. This is a great way to experiment and learn more about the language! Unfortunately, if you're using the CoffeeScript console to follow along, there isn't a great way to see the compiled output (most of the time, it's nice to have all that out of sight—just not right now!). You can see the compiled JavaScript in several other easy ways, though. The first is to put your code in a file and compile it. The other is to use the Try CoffeeScript tool on http://coffeescript.org/. It brings up an editor right in the browser that updates the output as you type.

CoffeeScript basics

Let's get started! We'll begin with something simple:

x = 1 + 1

You can probably guess what JavaScript this will compile to:

var x;
x = 1 + 1;

Statements

One of the very first things you will notice about CoffeeScript is that there are no semicolons. Statements are ended by a new line. The parser usually knows if a statement should be continued on the next line. You can explicitly tell it to continue to the next line by using a backslash at the end of the first line:

x = 1\
+ 1

It's also possible to stretch function calls across multiple lines, as is common in "fluent" JavaScript interfaces:

"foo"
.concat("barbaz")
.replace("foobar", "fubar")

You may occasionally wish to place more than one statement on a single line (for purely stylistic purposes). This is the one time when you will use a semicolon in CoffeeScript:

x = 1; y = 2

Both of these situations are fairly rare. The vast majority of the time, you'll find that one statement per line works great. You might feel a pang of loss for your semicolons at first, but give it time. The calluses on your pinky finger will fall off, your eyes will adjust to the lack of clutter, and soon enough you won't remember what good you ever saw in semicolons.

Variables

CoffeeScript variables look a lot like JavaScript variables, with one big difference: no var! CoffeeScript puts all variables in the local scope by default.

x = 1
y = 2
z = x + y

compiles to:

var x, y, z;
x = 1;
y = 2;
z = x + y;

Believe it or not, this is one of my absolute top favorite things about CoffeeScript. It's so easy to accidentally introduce variables to the global scope in JavaScript and create subtle problems for yourself. You never need to worry about that again; from now on, it's handled automatically. Nothing is getting into the global scope unless you want it there.

If you really want to put a variable in the global scope and you're really sure it's a good idea, you can easily do this by attaching it to the top-level object. In the CoffeeScript console, or in Node.js programs, this is the global object:

global.myGlobalVariable = "I'm so worldly!"

In a browser, we use the window object instead:

window.myGlobalVariable = "I'm so worldly!"

Comments

Any line that begins with a # is a comment. Anything after a # in the middle of a line will also be a comment.

# This is a comment.
"Hello" # This is also a comment

Most of the time, CoffeeScripters use only this style, even for multiline comments.

# Most multiline comments simply wrap to the
# next line, each begun with a # and a space.

It is also possible (but rare in the CoffeeScript world) to use a block comment, which begins and ends with ###. The lines in between these characters do not need to begin with a #.

###
This is a block comment. You can get artistic in here.
<(^^)>
###

Regular comments are not included in the compiled JavaScript, but block comments are, delineated by /* */.

Calling functions

Function invocation can look very familiar in CoffeeScript:

console.log("Hello, planet!")

Other than the missing semicolon, that's exactly like JavaScript, right? But function invocation can also look different:

console.log "Hello, planet!"

Whoa! Now we're in unfamiliar ground. This will work exactly the same as the previous example, though. Any time you call a function with arguments, the parentheses are optional. This also works with more than one argument:

Math.pow 2, 3

While you might be a little nervous writing this way at first, I encourage you to try it and give yourself time to become comfortable with it. Idiomatic CoffeeScript style eliminates parentheses whenever it's sensible to do so. What do I mean by "sensible"? Well, imagine you're reading your code for the first time, and ask yourself which style makes it easiest to comprehend. Usually it's most readable without parentheses, but there are some occasions when your code is complex enough that judicious use of parentheses will help. Use your best judgment, and everything will turn out fine.

There is one exception to the optional parentheses rule. If you are invoking a function with no arguments, you must use parentheses:

Date.now()

Why? The reason is simple. CoffeeScript preserves JavaScript's treatment of functions as first-class citizens.

myFunc = Date.now
#=> myFunc holds a function object that hasn't been executed
myDate = Date.now()
#=> myDate holds the result of the function's execution

CoffeeScript's syntax is looser, but it must still be unambiguous. When no arguments are present, it's not clear whether you want to access the function object or execute the function. Requiring parentheses makes it clear which one you want, and still allows both kinds of functionality. This is part of CoffeeScript's philosophy of not deviating from the fundamentals of the JavaScript language. If functions were always executed instead of returned, CoffeeScript would no longer act like JavaScript, and it would be hard for you, the seasoned JavaScripter, to know what to expect. This way, once you understand a few simple concepts, you will know exactly what your code is doing.

From this discussion, we can extract a more general principle: parentheses are optional, except when necessary to avoid ambiguity . Here's another situation in which you might encounter ambiguity: nested function calls.

Math.max 2, 3, Math.min 4, 5, 6

Yikes! What's happening there? Well, you can easily clear this up by adding parentheses. You may add parentheses to all the function calls, or you may add just enough to resolve the ambiguity:

# These two calls are equivalent
Math.max(2, 3, Math.min(4, 5, 6))
Math.max 2, 3, Math.min(4, 5, 6)

This makes it clear that you wish min to take 4 and 5 as arguments. If you wished 6 to be an argument to max instead, you would place the parentheses differently.

# These two calls are equivalent
Math.max(2, 3, Math.min(4, 5), 6)
Math.max 2, 3, Math.min(4, 5), 6

Precedence

Actually, the original version I showed you is valid CoffeeScript too! You just need to understand the precedence rules that CoffeeScript uses for functions. Arguments are assigned to functions from the inside out . Another way to think of this is that an argument belongs to the function that it's nearest to. So our original example is equivalent to the first variation we used, in which 4, 5, and 6 are arguments to min:

# These two calls are equivalent
Math.max 2, 3, Math.min 4, 5, 6
Math.max 2, 3, Math.min(4, 5, 6)

The parentheses are only absolutely necessary if our desired behavior doesn't match CoffeeScript's precedence—in this case, if we wanted 6 to be a argument to max. This applies to an unlimited level of nesting:

threeSquared = Math.pow 3, Math.floor Math.min 4, Math.sqrt 5

Of course, at some point the elimination of parentheses turns from the question of if you can to if you should. You are now a master of the intricacies of CoffeeScript function-call parsing, but the other programmers reading your code might not be (and even if they are, they might prefer not to puzzle out what your code is doing). Avoid parentheses in simple cases, and use them judiciously in the more complicated situations.

CoffeeScript Application Development Write code that is easy to read, effortless to maintain, and even more powerful than JavaScript with this book and ebook
Published: August 2013
eBook Price: $26.99
Book Price: $44.99
See more
Select your format and quantity:

Control structures

Control structures (such as if, else, and so on) in CoffeeScript share a foundation with JavaScript. We'll start out with some constructions that will feel familiar except some slightly different syntax. However, we'll then build on those basics and explore some new ways to express control flow.

So far, most of the CoffeeScript syntax we have covered has been somewhat superficial. Less punctuation makes code more readable (and prettier!), but CoffeeScript promises more than that. As we work through these control structures, you'll get a taste of some improvements that make CoffeeScript a more expressive language. Code isn't just machine instructions, it's also a form of communication. Good code not only works as intended, but communicates to other humans about what it is doing and how it is doing that. In this section we'll see some ways that CoffeeScript helps you communicate more effectively.

Using if statements

The first structure we'll look at is the standard if statement. Let's start off with a simple construction:

if (true == true)
console.log "Tautology!"

If you're trying out these examples in the CoffeeScript console, you'll need to enter multiline mode to do so – otherwise the console will try to execute the first line before you have a chance to enter the rest! Hit Ctrl-V on the first line of your statement to change to multiline mode. The prompt will change from coffee> to ------> to indicate that you've changed mode. Remember to enter the indentation for each line in the console, it's important! Here's what this statement will look like in the console:

------> if (true == true)
....... "f"

When you're finished, hit Enter to create a blank line, then hit Ctrl-V again to exit multiline mode. The console will now evaluate your statement and return a result.

If you've been following along with the other sections, you probably won't be surprised to hear that it's possible (and common) to eliminate the parentheses in the test statement:

if true == true
console.log "Tautology!"

You've probably noticed another omission by now: curly braces. CoffeeScript doesn't use curly braces for any code control structures like ifs, loops, or functions. Instead, it uses indentation to control code execution. Code that goes inside the if statement is indented beyond the level of the if statement. When CoffeeScript reaches a non-empty line that isn't indented to that level, it knows it has reached the end of the statement.

The idea of using whitespace semantically is born out of the observation that almost all languages encourage programmers to indent code for the sake of readability. In most languages, the whitespace is ignored by the machine, but it's expected by your fellow humans. Using whitespace semantically simply makes it important to both the machine and humans. Once the whitespace can convey instructions to the machine, other pieces of syntax become irrelevant and can be removed (in this case, curly braces).

Many programmers have trouble coming to terms with the idea of semantic whitespace. Python, as the most prominent language to use it, has taken a lot of flak for the choice. There are a few valid technical criticisms levelled against semantic whitespace (most notably that it is troublesome when cut-and-pasting code), but like many other hotly-debated issues, it generally comes down to a matter of taste.

If you're one of those people who feel squeamish about semantic whitespace, let me offer this comfort: I was (and occasionally still am) one of those people too. Even though I love CoffeeScript, I've never been completely sold on the whitespace. The good news is that it impacts your daily coding much less than you might expect. Whether or not you like the theory, in practice the whitespace issues will quickly fade into the background, and only rarely will you notice them at all. You'll come to appreciate the many other expressive features of the language, but you'll probably never think about the whitespace again as much as you have right now.

If you nest statements, you simply nest indentation levels as needed. CoffeeScript will know how to handle the successive levels of indentation.

number = 6
console.log "Let's test our number."
if number > 5
console.log "Our number is greater than 5"
if number > 10
console.log "Our number is greater than 10"
console.log "Now we're done testing."

Our CoffeeScript whitespace is transformed into the proper curly braces in JavaScript. Notice the correct nesting of if statements.

var number;
number = 6;
console.log("Let's test our number.");
if (number > 5) {
console.log("Our number is greater than 5");
if (number > 10) {
console.log("Our number is greater than 10");
}
console.log("Now we're done testing.");
}

The else and else if statements

You might be able to guess that else and else if statements are also available. They work much the same as in JavaScript, though again without the need for curly braces, and parentheses are optional.

number = -8
if number > 0
"Positive"
else if number < 0
"Negative"
else
"Zero"

The unless statement

Now let's look at something that doesn't have an exact equivalent in JavaScript. The unless statement behaves much like an if, but it executes the block if its test returns a false-ish value instead of a true-ish value.

day = "Monday"
unless day[0] == "S"
console.log "This is a weekday."

This can replace the common if (!test) form found in JavaScript. In fact, that is exactly what an unless block compiles to:

var day;
day = "Monday";
if (day[0] !== "S") {
console.log("This is a weekday.");
}

Using unless helps your code read more like spoken language – instead of reading as "if not this condition holds", it reads as "unless this condition holds". Using unless can also reduce errors. When reading code, it's easy to overlook a ! character and think that a whole block does the opposite of what it actually does. An unless keyword is much more obvious.

You can also use else and else if in combination with unless.

day = "Monday"
unless day[0] == "S"
console.log "This is a weekday."
else
console.log "It's the weekend!"

Be careful, though! It's easy to write confusing statements if you take this too far. Once you start adding alternatives, stop and ask yourself if you should refactor your code into something simpler (at this point, a standard if often makes the most sense).

Single-line form

A common pattern in code is the need to execute a single line if a condition holds. JavaScripters have developed a number of ways to handle that situation, like this:

if (true === true) {
console.log("Truth achieved!");
}

Or this:

if (true === true) { console.log("Truth achieved!"); }

Or this (my personal least favorite):

if (true === true)
console.log("Truth achieved!");

CoffeeScript has a simple way to deal with this pattern that is less error-prone and more readable. Simply put the if clause after the code to execute:

console.log "Truth achieved!" if true == true

This compiles into the first JavaScript form I showed you. See how the CoffeeScript version reads well as human language? "Do an action if these conditions are met." You can also use unless in this form, and it reads equally well.

console.log "Universe error!" unless true == true

Comparison operators

Now that we know how to use these control structures, let's learn about some comparison operators we can use to test the truthfulness of useful questions. There's one big surprise in here, so let's get that out of the way. == and != in CoffeeScript don't compile to their equivalents in JavaScript.

1 == 2
3 != 4

becomes:

1 === 2;
3 !== 4;

According to the CoffeeScript documentation, this decision was made because "the == operator frequently causes undesirable coercion, is intransitive, and has a different meaning than in other languages".

Most JavaScripters recommend using === and !== exclusively, so this is simply enshrining that best practice. If you wish to know more about this recommendation, read http://www.impressivewebs.com/why-use-triple-equals-javascipt/.

Other than that surprise, the other common JavaScript operators are all present and work as you might expect.

if 1 < 2 && 3 >= 2
if false || true
if !false
console.log "All is well."

However, CoffeeScript also provides a number of aliases to improve your code's readability. You can use is and isn't to test equality:

status = "normal"
reactor = "primed"
console.log "All clear" if status is "normal"
console.log "Abort mission" if reactor isnt "primed"

These aliases compile down to the ordinary JavaScript forms:

status = "normal";
reactor = "primed";
if (status === "normal") {
console.log("All clear");
}
if (reactor !== "primed") {
console.log("Abort mission");
}

You can use and , or, and not to combine truth values:

location = "Washington"
hairy = false
blurryPhoto = true
manInApeSuit = false
isBigfoot = location is "Washington" and (hairy or blurryPhoto)\
and not manInApeSuit

These too become the normal forms in JavaScript:

isBigfoot = location === "Washington" && (hairy || blurryPhoto)
&& !manInApeSuit;

In some languages, such as PHP and Ruby, the and keyword actually behaves differently than &&. In those languages there are subtle precedence differences between the two. Don't worry! That's not the case in CoffeeScript, since they both compile to the same result in JavaScript.

Even true and false have aliases. true can be written as yes or on, and false can be no or off. Use of these aliases is entirely optional, but you may find that a certain version is the most readable in any given situation.

power = true
mute = false
if power is on
playingMusic = yes if mute is off
else
playingMusic = no

Here's the JavaScript. Notice that using these aliases with is means we are strictly comparing against the boolean values, which is a little different than only testing the truthiness.

if (power === true) {
if (mute === false) {
playingMusic = true;
}
} else {
playingMusic = false;
}

Here's the whole table of comparison operators, from the CoffeeScript documentation. We'll look at in and of in the next two sections, when we deal with arrays and objects, respectively.

CoffeeScript

JavaScript

is

===

isnt

!==

not

!

and

&&

or

||

true, yes, on

true

false, no, off

false

@, this

this

of

in

in

no JS equivalent

CoffeeScript Application Development Write code that is easy to read, effortless to maintain, and even more powerful than JavaScript with this book and ebook
Published: August 2013
eBook Price: $26.99
Book Price: $44.99
See more
Select your format and quantity:

Arrays

Arrays, at their most simple, look very similar to JavaScript.

languages = [ "english", "spanish", "french" ]
console.log languages[1]

You may use a trailing comma and it will be compiled away:

languages = [
"english",
"spanish",
"french",
]

becomes:

var languages;
languages = ["english", "spanish", "french"];

Many people prefer this style, as it makes it easier to change the contents of an array or object. And you'll be thankful for this safeguard if you've ever left a trailing comma in a JavaScript array, only to discover (always at a very inconvenient time) that it causes an execution-halting error in one particular browser. The browser in question will remain unnamed for the sake of our collective blood pressure.

If you're feeling daring, you can eschew commas altogether. That's right! When the members of your array are declared on separate lines, you may omit the commas and CoffeeScript will still know what to do.

languages = [
"english"
"spanish"
"french"
]

Ranges

Sometimes, when declaring an array, you wish to initialize it with a simple range of values. It's tiresome to write out the values by hand, and difficult to check for errors once you're done. Luckily, there's a better way!

singleDigits = [0..9]

This compiles into a normal JavaScript array containing all elements in the range you specified.

var singleDigits;
singleDigits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

You can use descending order as well:

countdown = [10..1]

Two dots makes the range inclusive (meaning it will include the ending number you give it), while three dots make it exclusive (meaning it won't).

[1..5] == [1, 2, 3, 4, 5]
[1...5] == [1, 2, 3, 4]

You can even create a range using variables instead of literal numbers.

start = 0
end = 1000
bigNumbers = [start..end]

The generated JavaScript gets a little more complicated when the range uses anything other than number literals. If you want a quick brain teaser, check it out for yourself and see if you can decipher what it's doing.

var end, start, _i, _results;
start = 0;
end = 1000;

bigNumbers = (function() {
  _results = [];
  for (var _i = start;
     start <= end ? _i <= end : _i >= end;
     start <= end ? _i++ : _i--)
  { _results.push(_i); }
  return _results;
}).apply(this);

 

Loops

Iterating through the elements of an array has always been a bit of a sore point in JavaScript. The for loop is tried and true, but writing it out every time is a lot of unnecessary keystrokes, and makes your code more verbose. There's the functional-style Array.prototype.forEach, which works well but isn't supported in every browser (I think we all know who the culprit is). And some libraries, such as jQuery or Underscore.js, provide their own iteration utilities, but of course those are only available if you have the library loaded up. What to do? Why, use CoffeeScript, of course!

animals = ["dog", "cat", "bird"]
for animal in animals
console.log animal

As usual, the generated JavaScript looks very much like something you or I might write:

var animal, animals, _i, _len;
animals = ["dog", "cat", "bird"];
for (_i = 0, _len = animals.length; _i < _len; _i++) {
animal = animals[_i];
console.log(animal);
}

If the body of our loop only contains one statement, we can declare the whole thing on a single line, with the for at the end (just like we could do with if and unless earlier). The preceding example could be rewritten like this:

animals = ["dog", "cat", "bird"]
console.log animal for animal in animals

One extremely useful feature of CoffeeScript loops is that they return a value—an array of the results of the inner statement for every item in the loop. If you've ever used Array.prototype.map to transform an array, you'll be happy to see that it's easy to achieve the same functionality in CoffeeScript.

animals = ["dog", "cat", "bird"]
pluralAnimals = for animal in animals
animal + "s"

If we look at the compiled JavaScript, we can see that it's still using a for loop. It's just doing an extra bit of work to push the results into an array that's returned at the end:

var animal, animals, pluralAnimals;
animals = ["dog", "cat", "bird"];
pluralAnimals = (function() {
var _i, _len, _results;
_results = [];
for (_i = 0, _len = animals.length; _i < _len; _i++) {
animal = animals[_i];
_results.push(animal + "s");
}
return _results;
})();

We can also shorten our operation to a single line. There's one catch to be aware of, though. What do you notice about the following code?

animals = ["dog", "cat", "bird"]
pluralAnimals = (animal + "s" for animal in animals)
console.log pluralAnimals

After we've spent all this time cutting out unneeded parentheses, it seems strange that I'm adding a set around this statement. As it turns out, they are needed. To see why, you'll need to understand how CoffeeScript handles precedence with assignment and loops. What if we wrote it without the parentheses, like this?

pluralAnimals = animal + "s" for animal in animals

The assignment has a higher precedence, so that version works out like this:

(pluralAnimals = animal + "s") for animal in animals

The assignment takes place inside the loop for each member of the array, so when we examine pluralAnimals at the end, we'll find it holds the value of the last transformed element, in this case, "birds". This usually isn't what we want, so we put parentheses around the for loop. This ensures that the result of the entire loop is what's assigned to our variable

Loop comprehensions

Iterating through an array is nice, but it's time to get fancier. We'll often find that we want to loop through an array, but only act on elements which meet a certain criteria. We can do this by putting if statements inside our loop, but there's a much better way. CoffeeScript lets us attach guards—conditional statements that filter the loop execution—using the when keyword.

words = ["dogma", "catastrophe", "doggerel", "hangdog"]
for word in words when word.indexOf("dog") isnt -1
console.log word

Sure enough, when compiled to JavaScript, the guard appears as an if statement inside the loop.

var word, words, _i, _len;
words = ["dogma", "catastrophe", "doggerel", "hangdog"];
for (_i = 0, _len = words.length; _i < _len; _i++) {
word = words[_i];
if (word.indexOf("dog") !== -1) {
console.log(word);
}
}

Let's combine a few of the array tricks we've learned. We can assign the result of a loop with guards to a variable, and it will store an array of only the values that met the criteria. And remember how ranges helped us easily build arrays of sequential numbers? Turns out ranges are very useful when combined with loops.

evenNumbers = (n + " is even" for n in [1..100] when n % 2 is 0)

There's a lot happening on that line, but it's not so bad once we break it apart. We start with an array of the numbers from 1 to 100. We iterate through the array, only operating on numbers that are divisible by 2. For every number that fits this criteria, we turn it into a string. Our evenNumbers variable is then assigned to hold the array of resulting strings.

A few more array tricks

There's even more that we can do with loop comprehensions in CoffeeScript, although we'll use these features less frequently.

Occasionally we'll want to iterate through an array, but we'll need access to the index of the element we're currently working with. In these situations, for can take a second argument that holds the current index.

solarSystem = [
"Mercury"
"Venus"
"Earth"
"Mars"
"Jupiter"
"Saturn"
"Uranus"
"Neptune"
"Pluto"
]
for planet, planetIndex in solarSystem when planet isnt "Pluto"
console.log "Planet #" + (planetIndex+1) + " is " + planet

We may also have an occasional need to iterate through every nth member of an array—every second item, or every fifth item, or whatever the situation calls for. CoffeeScript makes this easy with the by keyword. We can rewrite our even-number example using this instead of the modulo operator. Only we'll need to start at 2, because by starts counting with the first item of the array.

evenNumbers = (n for n in [2..100] by 2)

Checking array membership

We've used the in keyword while iterating through arrays, but it serves double duty. We can also use it to check for membership in an array.

number = 3
if number in [2, 3, 5, 7, 11, 13]
console.log number + " is prime!"

The compiled JavaScript for this is very straightforward. Because CoffeeScript has access to the array, it simply splits the values out into different equality tests.

var number;
number = 3;
if (number === 2 || number === 3 || number === 5 || number === 7 ||
number === 11 || number === 13) {
console.log(number + " is prime!");
}

We can also use in for more advanced situations, such as when the array is dynamic.

planets = [ "Mercury", "Venus", "Earth", "Mars",
"Jupiter", "Saturn", "Uranus", "Neptune", ]
console.log "Hooray!" if "Pluto" in planets

The compiled JavaScript for this situation behaves the same way, but by necessity is somewhat more complex:

var planets,
__indexOf = [].indexOf || function(item) {
for (var i = 0, l = this.length; i < l; i++) {
if (i in this && this[i] === item) return i;
}
return -1;
};

planets = ["Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn",
"Uranus", "Neptune"];
if (__indexOf.call(planets, "Pluto") >= 0) {
console.log("Hooray!");
}

You can see that CoffeeScript has defined a small utility function in this example, named __indexOf. Several of these helper functions will appear over time. They allow CoffeeScript to generate code that is compatible with every JavaScript runtime and doesn't rely on any external libraries. These helpers are kept small and efficient, and luckily CoffeeScript is smart enough to only generate them once per file.

Simple objects

You have no doubt spent a lot of time working with objects in JavaScript. They are the most versatile data structure in the language, and JavaScript encourages heavy use of them. CoffeeScript keeps all that great support for objects, and adds a few helpful features for dealing with them.

Declaring an object looks very familiar. Let's record a few biographical details:

author = { name: "Ian", age: 26 }

We can still access object properties like we do in JavaScript:

author.name
author["age"]
author.favoriteLanguage = "CoffeeScript"

Just like CoffeeScript arrays, if we declare the object properties on different lines, we can optionally omit the commas.

authorsBicycle = {
color: "black"
fenders: true
gears: 24
}

That's not all! We can also omit the curly braces. This is possible on both the single-line and multi-line versions.

author = name: "Ian", age: 26, favoriteLanguage: "CoffeeScript"
authorsBicycle =
color: "black"
fenders: true
gears: 24

This even works with nested objects. If we omit the curly braces, CoffeeScript uses the indentation to determine the structure of the object.

authorsBicycle =
color: "black"
brand:
make: "Surly"
model: "Cross Check"
fenders: true
gears: 24

This compiles to a nested object:

var authorsBike;
authorsBike = {
color: "black",
brand: {
make: "Surly",
model: "Cross Check"
},
fenders: true,
gears: 24
};

Iterating over objects

Happily, CoffeeScript also makes it easy to iterate over the properties of an object. Remember, we iterated over arrays using for item in array. Objects have a very similar syntax, but use the of keyword instead of in. This can be a little confusing if you think back to the in keyword in JavaScript, so try to put that out of your mind. I remember the difference by thinking of describing it in English: you have items in an array, but you have properties of an object. The loop takes two values, the key and value of the property.

author = name: "Ian", age: 26, favoriteLanguage: "CoffeeScript"
for k, v of author
console.log "My " + k + " is " + v

The compiled JavaScript is again a very simple implementation, using the in JavaScript keyword (which we're still not thinking too hard about lest we get confused again).

for (k in author) {
v = author[k];
console.log("My " + k + " is " + v);
}

Summary

We've covered a lot of ground in this article. We learned:

  • How to use variables.
  • How to call functions.
  • How to use if/else statements and their counterpart, unless.
  • How to use natural-language aliases to make our comparison statements more readable.
  • How to declare arrays, and iterate through their contents in a number of different ways.
  • How to declare and iterate over objects.

Not only did we learn about all those things, but we made sure to avoid a few common mistakes, and learned why it was possible to make those mistakes. We've compared many of the CoffeeScript statements to the compiled JavaScript, so hopefully you're developing a good mental map of how CoffeeScript translates to JavaScript.

Resources for Article :


Further resources on this subject:


About the Author :


Ian Young

Ian Young wrote his very first program on a TI-89 scientific calculator—an infinite loop that printed an insulting message to one of his friends. As one might expect, things could only improve from there. Ian graduated from Grinnell College with a degree in Computer Science, and since then has been working as a web developer for small tech companies; first in Minneapolis and now in San Diego. He loves web technology, small teams, frequent iteration, testing, beautiful ideas, free speech, free beer, and any tool that reduces cognitive overhead.

Books From Packt


CoffeeScript Programming with jQuery, Rails, and Node.js
CoffeeScript Programming with jQuery, Rails, and Node.js

jQuery Game Development Essentials
jQuery Game Development Essentials

PhoneGap 2.x Mobile Application Development Hotshot
PhoneGap 2.x Mobile Application Development Hotshot

 Object-Oriented JavaScript
Object-Oriented JavaScript

PhoneGap Mobile Application Development Cookbook
PhoneGap Mobile Application Development Cookbook

iPhone JavaScript Cookbook
iPhone JavaScript Cookbook

Learning JavaScriptMVC
Learning JavaScriptMVC

Sencha Touch Mobile JavaScript Framework
Sencha Touch Mobile JavaScript Framework


No votes yet

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
8
d
Y
3
e
6
Enter the code without spaces and pay attention to upper/lower case.
Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software