位元詩人 技術雜談: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) 是資訊領域碩士,專注於從探索到產品的開發過程,並以工具驅動的方式改善專案。喜歡以開源專案作為成果,回饋社群。

主要方向包括:自用工具的打磨 (dogfooding)、編譯器技術在工具開發中的應用,以及將研究轉化為可維護的開源成果。

除了技術之外,也喜歡日本料理和黑咖啡,偶爾自助旅行,將生活中的靈感融入技術隨筆。