CoffeeScript is a tiny language which compiles into JavaScript. Its expressive, yet terse syntax dramatically increases the readability of your code, which in turn makes it easier to maintain and less likely to contain bugs. In the words of its creator, Jeremy Ashkenas, CoffeeScript allows you to “write what you mean, instead of writing within the limits of historical accident”.
An additional benefit to writing CoffeeScript is that the JavaScript it compiles to will run in older versions of Internet Explorer. CoffeeScript also lets you forget about common JS pitfalls, such as trailing commas and automatic semicolon insertion.
And it’s gaining in popularity! Spurred on by its adoption in the Rails community (Rails 3.1+ ships with built-in CoffeeScript support), CoffeeScript recently entered the Tiobe index of the top 100 programming languages, where it was raked in 64th place. This was ahead of Dart (66th place) and TypeScript (not listed), both of which also compile to JavaScript.
So are you ready to give CoffeeScript a try? In this article I will demonstrate how to install it, as well as its basic concepts.
Installation
You can install CoffeeScript globally using the Node Package Manager (npm) by typing the following command in to your terminal:
npm install coffee-script -g
You should install it globally so you can later access it in terminal with the command coffee
.
If you need a primer on using npm, then please refer to this recently published SitePoint article.
Compilation
CoffeeScript files have the .coffee
file extension. These files are either manually compiled, or you set a watcher that will compile your script each time it is saved with different contents.
To compile manually, go to the directory where the script is:
cd E:\apps\something\logic
And run the following command:
coffee -c app.coffee
This will create an app.js
file in the same directory which you can then include in your project.
However, you most likely want app.js
to be refreshed each time you save the file. Therefore you compile it and add a watcher by typing:
coffee -cw app.coffee
Please note that in the latest version of CoffeeScript (1.9.1) there is a bug that causes the watcher not to work. All of the following examples were tested using CoffeeScript v 1.9.0.
CoffeeScript Basics
In CoffeeScript you do not have to declare variables as you do in JavaScript, although often you would need to set an initial value. We also do not have to type semi-colons ( ;
) at the end of a line.
This means that you write:
hasBody = true
instead of :
var hasBody = true;
You can also call functions without using parentheses, but that is desirable only for outermost function calls. Therefore, you can do the following:
$(".messages") .show 'slow'
instead of:
$(".messages").show('slow');
Indentation matters a lot in CoffeeScript. You should indent with two spaces or a tab:
if hasBody
alert "Hello Body"
else
alert "No Body"
Booleans and Conditionals
In CoffeeScript the keywords on
, yes
and true
are all equivalent and refer to the Boolean true
, whereas off
, no
and false
are also equivalent and refer to the Boolean false
.
You can use is
and isnt
to check for equality or lack of equality ( ===
and !==
) .
You can use then
to make single-line conditional statements.
You can use and
and or
to refer to &&
and ||
respectively.
All of which means that you can compare a value to two other values without repeating yourself.
An example of these concepts:
x = 53
y = 40
z = 33
b = true
if b is on and x is 53 and z < y > 11 then alert "ALRIGHT!"
The final statement compiles to:
if (b === true && x === 53 && (z < y && y > 11)) {
alert('ALRIGHT!');
}
Iteration, Filters and Ranges
The for .. in
syntax in CoffeeScript is used for iterating over an array, while a for .. of
loop is used for iterating over the properties of an object.
arr = [1, 2, 3]
for val in arr
console.log(val);
spartacus =
type: "cat"
legs: 4
fur: yes
for key, value of spartacus
console.log "#{key}: #{value}"
Notice the string interpolation in the final statement. This is achieved using a #{variableName}
syntax.
This will output:
1
2
3
type: cat
legs: 4
fur: true
You can combine this with CoffeeScript’s when
keyword to filter items in an array:
spartacus =
type: "cat"
legs: 4
fur: yes
shrimpy =
type: "fish"
legs: 0
fur: no
pets = [spartacus, shrimpy]
myPet = pet for pet in pets when pet.type is "cat"
console.log myPet
Outputs:
Object {type: "cat", legs: 4, fur: true}
Notice that you can specify the statement to be executed in the loop before you write the loop. This is useful when writing one-liner loops.
This could also be written as:
for pet in pets when pet.type is "cat"
myPet = pet
console.log myPet
An extremely useful feature of CoffeeScript is the ability to create numeric ranges. These can be inclusive and exclusive:
someValues = [0..10]
sameValues = [0...11]
When compiled to JavaScript the arrays look like this:
someValues = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
sameValues = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
If you create a range with more than 20 elements, CoffeScript gets a little clever, as you can see from the generated JavaScript. Notice that execution takes place in an anonymous function to ward against scope leakage and variable conflict.
var someValues, _i, _results;
someValues = (function() {
_results = [];
for (_i = 0; _i <= 21; _i++){ _results.push(_i); }
return _results;
}).apply(this);
Functions and the “this” Keyword
To create functions you use ->
followed by the definition. If you have to add parameters you add them inside parenthesis () before the ->
You can add default values by setting the parameter to equal something.
Examples of functions with CoffeeScript:
myCoffee = ->
console.log "C'est un cafe"
makeCoffee = (brand = "Hogwarts") ->
console.log "Making a coffee #{brand}-style"
myCoffee()
makeCoffee()
Logs to the console:
C'est un cafe
Making a coffee Hogwarts-style
You can use @
instead of the this
keyword:
$("a").click ->
$(@).hide 'slow'
This compiles to:
$("a").click(function() {
return $(this).hide('slow');
});
ES6 Style Classes and OOP
CoffeeScript facilitates object-oriented programming and inheritance as well. You can define classes like this:
class Animal
constructor: (@name, @breed) ->
@.introduce = ->
console.log "Hi, I am #{@.name}, one hell of a #{@.breed}"
husky = new Animal("Johnny", "Siberian Husky")
husky.introduce()
Outputs in console:
Hi, I am Johnny, one hell of a Siberian Husky
typing @
before the parameter’s name in the constructor, causes the parameter to be immediately set in the constructor. Alternatively, you could just write @.name = name
in the constructor function.
You can extend classes as well:
class Dog extends Animal
Dog.prototype.bark = ->
console.log "#{@name} barks!"
newHusky = new Dog("Lassy", "Labrador Husky")
newHusky.introduce()
newHusky.bark()
This code outputs:
Hi, I am Lassy, one hell of a Labrador Husky
Lassy barks!
Your functions can accept an unlimited number of arguments if you add ...
(ellipsis) after the parameter. In this case, all values after and including that parameter are added in the form of an array.
Here is how you could achieve that:
showAwards = (awards...) ->
console.log ("Awards collected : #{awards.join ', '}")
showAwards "Award 1", "Award 2", "Award 3"
The code above outputs:
Awards collected : Award 1, Award 2, Award 3
The final thing I want to mention here is that when you are inside any function CoffeeScript automatically returns the result from the last statement executed. Therefore, all your functions have an implicit return value (just as you saw in the anonymous function that handles anchor clicks above).
Conclusion
In this article I have demonstrated many of the features that make CoffeeScript such a pleasure to work with. I will build on this knowledge in a future article when I will use CoffeeScript to create the well-known game TicTacToe. Until then, let me know what you think: Are you using CoffeeScript already? Has this article made you curious to try it out? Or does CoffeeScript offer nothing more than an unnecessary layer of complexity?
Frequently Asked Questions (FAQs) about Accelerating JavaScript Development with CoffeeScript
What is the main difference between JavaScript and CoffeeScript?
JavaScript and CoffeeScript are both scripting languages, but they have some key differences. JavaScript is a high-level, interpreted programming language that is primarily used for web development. On the other hand, CoffeeScript is a little language that compiles into JavaScript. It provides better syntax avoiding the quirky parts of JavaScript, offering a cleaner and more readable code. However, it’s important to note that CoffeeScript is not a standalone language, it needs to be compiled into JavaScript before it can run.
How does CoffeeScript accelerate JavaScript development?
CoffeeScript accelerates JavaScript development by providing a more concise and readable syntax, which makes the code easier to write and maintain. It eliminates unnecessary characters and uses indentation to define code blocks instead of curly braces, which reduces the chances of syntax errors. Moreover, CoffeeScript includes additional features not present in JavaScript, such as array comprehensions and destructuring assignment, which can make your code more efficient.
Can I use pure JavaScript inside of CoffeeScript?
Yes, you can use pure JavaScript inside of CoffeeScript. This is done by wrapping the JavaScript code in backticks (`). This tells the CoffeeScript compiler to ignore the code within the backticks and leave it as is. This can be useful when you need to use a JavaScript function or feature that is not available or not easily expressed in CoffeeScript.
How do I convert my JavaScript code to CoffeeScript?
Converting JavaScript code to CoffeeScript can be done using various online tools like js2coffee. You simply paste your JavaScript code into the tool and it will output the equivalent CoffeeScript code. However, it’s important to understand that these tools may not always produce perfect results, and you may need to manually adjust the output to ensure it works as expected.
Is CoffeeScript widely used in the industry?
While CoffeeScript was quite popular a few years ago, its usage has declined with the rise of modern JavaScript and other compile-to-JavaScript languages like TypeScript. However, it is still used in some projects and can be a useful tool to learn, especially if you’re working on a project that already uses it.
What are the benefits of using CoffeeScript over JavaScript?
CoffeeScript offers several benefits over JavaScript. It has a cleaner, more readable syntax that eliminates many of the quirks of JavaScript. It also includes additional features like array comprehensions and destructuring assignment, which can make your code more efficient. However, it’s important to note that CoffeeScript is not a replacement for JavaScript, but rather a tool that compiles into JavaScript.
Can I use CoffeeScript with Node.js?
Yes, you can use CoffeeScript with Node.js. In fact, CoffeeScript was originally designed with Node.js in mind. You can write your Node.js scripts in CoffeeScript and then compile them into JavaScript using the CoffeeScript compiler.
How do I install CoffeeScript?
CoffeeScript can be installed using npm, the Node.js package manager. You simply run the command npm install -g coffee-script
in your terminal or command prompt. This will install CoffeeScript globally on your system, allowing you to use the coffee
command to compile your CoffeeScript files into JavaScript.
Is CoffeeScript compatible with all JavaScript libraries?
Yes, since CoffeeScript compiles into JavaScript, it is compatible with all JavaScript libraries. You can use any JavaScript library in your CoffeeScript code just as you would in JavaScript.
How do I debug CoffeeScript code?
Debugging CoffeeScript code can be a bit tricky since the code that is actually running is the compiled JavaScript, not the original CoffeeScript. However, CoffeeScript includes a feature called source maps that can help with this. A source map is a file that maps the compiled JavaScript back to the original CoffeeScript, allowing you to debug the CoffeeScript directly.
Ivan is a student of IT, a freelance web developer and a tech writer. He deals with both front-end and back-end stuff. Whenever he is not in front of an Internet-enabled device he is probably reading a book or travelling.