位元詩人 技術雜談:CoffeeScript - the Sugar of JavaScript

Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email

JavaScript is the vital part of modern interactive web. However, JavaScript is not easy; it mixes the features of several languages. Some good, some bad. The syntax is Java-esque but the underlying concepts is totally different from Java. CoffeeScript is a mini-language that compiles into JavaScript. It brings an elegant Python or Ruby-like syntactic sugar for JavaScript and helps you to avoid some JavaScript pitfalls.

Here is an example of CoffeeScript:


# a function
square = (x) -> x * x

# an object
math =
  root: Math.sqrt
  square: square
  cube: (x) -> x * square x

# an array
list = [1..5]

# list comprehension in coffeescript
cubes = (math.cube num for num in list)

console.log cubes
{{< / highlight >}}

The above examples are compiled into the following equivalent JavaScript:

```javascript
var cubes, list, math, num, square;

square = function(x) {
  return x * x;
};

math = {
  root: Math.sqrt,
  square: square,
  cube: function(x) {
    return x * square(x);
  }
};

list = [1, 2, 3, 4, 5];

cubes = (function() {
  var _i, _len, _results;
  _results = [];
  for (_i = 0, _len = list.length; _i < _len; _i++) {
    num = list[_i];
    _results.push(math.cube(num));
  }
  return _results;
})();

console.log(cubes);
{{< / highlight >}}

As you see, the code is shorter and more readable in CoffeeScript than in JavaScript.  Besides, CoffeeScript add several sugars for JavaScript.  For example, auto-generated list and list comprehension seen in the above code snippet.  You may check the official site of CoffeeScript to see more examples.

There are still other good things of CoffeeScript.  For instance, CoffeeScript warp the function by default to avoid global variable space contamination.

```coffeescript
gcd = (x, y) ->
  [x, y] = [y, x % y] while y != 0
  return x
{{< / highlight >}}

The above example will be compiled into:

```javascript
(function() {
  var gcd;

  gcd = function(x, y) {
    var _ref;
    while (y !== 0) {
      _ref = [y, x % y], x = _ref[0], y = _ref[1];
    }
    return x;
  };
}).call(this);
{{< / highlight >}}  

Another feature of CoffeeScript is block regular expression, which supports better regex code.  This is a regex pattern checking domain name in CoffeeScript:

```coffeescript
domain_name = ///
   \b
   (
     # ftp://, http:// or https:// leadning part
     (ftp|https?)://[-\w]+(\.\w[-\w]*)+
   |
     # or, try to find a hostname
     (?i: [a-z0-9] (?:[-a-z0-9]*[a-z0-9])? \. )+
     # top domain name
     (?-i: com\b
         | edu\b
         | biz\b
         | in(?:t|fo)\b # .int or .info
         | mil\b
         | net\b
         | org\b
         | [a-z][a-z]\b # two-letter country codes
      )
   ) ///
{{< / highlight >}}

It is more readable than their JavaScript equivalent.  Besides, you can add comment inside your regex pattern, which is an eye candy.

```javascript
var domain_name = /\b((ftp|https?):\/\/[-\w]+(\.\w[-\w]*)+|(?i:[a-z0-9](?:[-a-z0-9]*[a-z0-9])?\.)+(?-i:com\b|edu\b|biz\b|in(?:t|fo)\b|mil\b|net\b|org\b|[a-z][a-z]\b))/;
{{< / highlight >}}

Since CoffeeScript will be compiled into JavaScript, JavaScript libraries are supported.  For example, a client-side CoffeeScript code using jQuery:

```coffeescript
$("p").hover(
  () ->
    $(@).css "background-color", "#ffff00"
  ,
  () ->
    $(@).css "background-color", "white"
)
{{< / highlight >}}

Node.js libraries are supported as well.  Let's see a hello-world Express.js example written in CoffeeScript:

```coffeescript
express = require 'express'
http = require 'http'

app = express()

app.get '/', (req, res) ->
  res.send "Hello, World!"

http.createServer(app).listen(4000)
{{< / highlight >}}

Compile the example into JavaScript code and you'll get a simple Node.js application.

If you want to give CoffeeScript a try, you can download `coffee-script` as a Node.js app and install it globally.

```console
$ npm install coffee-script -g  # install CoffeeScript
$ coffee -c code.coffee         # compile code.coffee into code.js
{{< / highlight >}}

Alternatively, you can try some CoffeeScript snippet on the CoffeeScript website. (At **Try CoffeeScript** region.)

Although CoffeeScript cannot totally eliminate the pitfalls of JavaScript, CoffeeScript brings you the good parts.  "Writing in CoffeeScript; reading in JavaScript" becomes a possible mode to do JavaScript programming.
關於作者

位元詩人 (ByteBard) 是資訊領域碩士,喜歡用開源技術來解決各式各樣的問題。這類技術跨平台、重用性高、技術生命長。

除了開源技術以外,位元詩人喜歡日本料理和黑咖啡,會一些日文,有時會自助旅行。