位元詩人 技術雜談: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) 認為開發應用程式的目的是為社會帶來價值。如果在這個過程中該軟體能成為永續經營的項目,那就是開發者和使用者雙贏的局面。

位元詩人喜歡用開源技術來解決各式各樣的問題,但必要時對專有技術也不排斥。閒暇之餘,位元詩人將所學寫成文章,放在這個網站上和大家分享。