Learn CoffeeScript

Ngôn ngữ lập trình CoffeeScript

Được xây dựng dựa trên JavaScript và nó biên dịch thành JavaScript để bạn có thể chạy trên một trình duyệt web hoặc sử dụng với các công nghệ như Node.js cho các ứng dụng máy chủ. Việc biên dịch đơn giản và các đoạn mã JavaScript được tạo ra một cách phù hợp nhất. Trong bài viết này, hãy tìm hiểu về các tính năng của ngôn ngữ lập trình CoffeeScript. Sau khi cài đặt CoffeeScript và chạy trình biên dịch này, bạn sẽ thực hiện từng bước thông qua một ví dụ đơn giản có sử dụng CoffeeScript trong trang web.

CoffeeScript giải quyết những điểm yếu chính của JavaScript:

  • Cung cấp một cú pháp đơn giản hơn, làm giảm sự rập khuôn, chẳng hạn như các dấu ngoặc đơn và các dấu phẩy.
  • Sử dụng khoảng trắng như là một cách để tổ chức các đoạn mã.
  • Cung cấp cú pháp đơn giản để thể hiện các hàm.
  • Cung cấp sự thừa kế dựa trên lớp (đó là tùy chọn, nhưng có thể rất có ích khi tiến hành phát triển ứng dụng)

Bạn thắc mắc so với JavaScript thì CoffeeScript có chậm hơn nhiều so với JavaScript không hoặc nó có yêu cầu một thư viện nặng nề để chạy không? Trong thực tế, CoffeeScript biên dịch thành JavaScript rõ ràng, hiệu quả. Bạn luôn có thể nhìn thấy chính xác nó đang biên dịch thành những gì, vì vậy bạn có thể yên tâm là không có gì được đưa vào quá mức. Và, vì CoffeeScript biên dịch thành JavaScript với đầy đủ tính năng, nên không cần dùng thêm bất kỳ một thư viện nào để chạy. CoffeeScript cung cấp một cú pháp cho phép bạn khai thác đầy đủ sức mạnh của JavaScript.

**Một số đặc trưng cơ bản của CoffeeScript **

  • Coffeescript đã thay đổi ngôn ngữ của JavaScript từ một ngôn ngữ lập trình khá cứng nhắc thành một ngôn ngữ gần gũi với văn viết thông thương hơn, giúp người đọc code và lập trình dễ hiểu hơn.
  • Các biến trong CoffeeScript không cần khai báo kiểu var trước. Kết thúc dòng lệnh không cần dấu ; mà đơn giản chỉ là xuống dòng.
  • Các khối kệnh không còn cần dấu {} để mở đầu và kết thúc, các bạn chỉ cần thụt vào đầu dòng.
  • Tuy nhiên cũng có một số điểm yếu mà CoffeeScript mắc phải như là sẽ khó khăn hơn trong việc bắt lỗi khi mà chỉ cần sai một dấu cách dòng cũng có thể làm cho CoffeeScript không chạy.

Cú pháp trong CoffeeScript

  1. Functions

    Đầu tiên ta thử xem các hàm trong CoffeeScript được viết ra sao:

    square = (x) -> x * x
    square = function() {
        return x * x;
    };
Trong ví dụ trên thì các biến hay hàm của CoffeeScript không phải khai báo trước. Hàm `square` được viết một các đơn giản, không cần  `{}` như trong JavaScript. Viết hàm trong CoffeeScript đơn giản hơn rất nhiều JavaScript với cú pháp đơn giản, dễ nhớ, đặc biệt ngắn gọn hơn rất nhiều so với JavaScript.

Một ví dụ khi dùng attribute, bạn có thể lược bỏ khá nhiều dấu (){}

    $(.my-class).attr class: ‘active’
    $('.account').attr({
        "class": 'active'
    });
    log(object["class"]);
Cách gọi hàm trong CoffeeScript cũng khá là đơn giản. Như trong ví dụ dưới đây
    outer = 1
    changeNumbers = ->
        inner = -1
        outer = 10
    inner = changeNumbers()
    outer = 1;
    changeNumbers = function() {
        var inner;
        inner = -1;
        return outer = 10;
    };
    inner = changeNumbers();
Nhìn vào đoạn trên ta thấy rằng không hề có việc khai báo biến trong CoffeeScript. Trình biên dịch của CoffeeScript luôn luôn đảm bảo khai báo đầy đủ biến cho bạn, bạn không bao giờ phải lo lắng về việc chưa khai báo biến.

_**Chú ý:**_  Ở ví dụ trên bạn cần chú ý biến inner trong hàm `changeNumbers()` khác với biến inner ở ngoài, nên tốt nhất bạn nên đặt tên biến rõ ràng để đảm bảo việc sử dụng không bị nhầm lẫn.

Và đặc biệt là sau khi biên dịch thì tất cả phần output sẽ được đặt trong:

`(function() {.....})();`
  1. Các câu lệnh có điều kiện như if, else..

    Cấu trúc của if/else trong CoffeeScript được lược bỏ dấu ngoặc chứa điều kiện và ngoặc nhọn chứa các khối lệnh kết quả. Các mệnh đề if, then , else hay unless được sử dụng khá linh hoạt, câu lệnh và điều kiện có thể đổi chỗ cho nhau, các phương thức so sánh khá giống văn viết thông thường với các toán tử so sánh.

    mood = greatlyImproved if singing
    if happy and knowsIt
        clapsHands()
        chaChaCha()
    else
        showIt()
    date = if friday then sue else jill
    var date, mood;
    if (singing) {
        mood = greatlyImproved;
    }
    if (happy && knowsIt) {
        clapsHands();
        chaChaCha();
    } else {
        showIt();
    }
    date = friday ? sue : jill;
  1. Vòng lặp : switch, for

    Hàm switch trong CoffeeScript đã không còn cần dùng đến break, case. Nó được thay bằng cú pháp:

    switchwhenthenwhenthen …
        …
    else
Cách viết này khá là đơn giản, ngắn gọn và bạn cũng không cần phải nhớ đến `break` sau mỗi `case` như thường lệ. Nếu xuống dòng sau mỗi lệnh `when` thì không cần có `then` đằng sau đó.
Cùng xét ví dụ sau:
    printf = (day) ->
        switch day
            when “Monday”, “Tuesday”
                alert “Go to work”
             when “Friday”
                 alert “Go to Bank”
             else
                 alert “Go to picnic”
    print(“Sunday”)
    var print;
    print = function (day) {
        switch (day) {
            case "Monday":
            case "Tueday":
                return alert("Go to work");
            case "Friday":
                return alert("Go to Bank");
            default:
                return alert("Go to picnic");
        }
    };
    print("Sunday");
Kết quả ta nhận được sẽ là thông báo “Go to picnic”

Vòng lặp trong CoffeeScript được biến đổi khá thú vị. Vòng lặp ` for` dài dòng bây giờ có thể chỉ là 1 dòng ngắn gọn. Mảng danh sách cũng đơn giản và ngắn gọn hơn.

Ví dụ bạn muốn khai báo ra danh sách từ 1 -> 10 thì chỉ cần viết

    for num in [10..1]
        alert num
    var num, _ i;
    for (num = i = 10; i >= 1; num = -- 1) {
        alert(num);
    }
  1. Splats…

    Đôi khi chúng ta cái đặt một hàm mà các tham số có trong hàm dynamic, chúng ta không biết nó có bao nhiều tham số, đôi lúc là 1, thậm chí 100… Coffeescript giúp chúng ta giải quyết việc này bằng cách dùng chức năng splats, khi định nghĩa 1 danh sách tham số của hàm ta sẽ thêm dấu … Xét ví dụ như sau

    splatter = (etc…) ->
        alert "length: #{etc.length}, Value: "
    splatter = (etc…) ->
        alert "Length: #{etc.length}, Values: #{etc.join(‘, ’)}"
    splatter()
    splatter(‘a’, ‘b’, ‘c’)
    var splatter;
    splatter = function(etc…) {
        return Alert("length: " + etc.length + ", Value: ");
    };
    splatter = function(etc…) {
        return Alert("Length: " + etc.length + ", Values: " + (etc.join(,)));
    };
    splatter();
    splatter(‘a’, ‘b’, ‘c’);
Kết quả ta nhận được ở 2 lần gọi hàm `splatter()` là :

`Lần 1: Length: 0, Values:`

`Lần 2: Length: 3, Values: a,b,c`

Ta có thể đặt splats ở mọi nơi trong hàm đều được, nó sẽ đi theo thứ tự là ưu tiên check tất cả các biến `static` trước cuối cùng còn bao nhiêu biến mới dồn vào `splats` sau cùng.
  1. Các toán tử so sánh trong CoffeeScript:

    Trong CoffeeScript các toán tử so sánh, Boolean và 1 số toán tử có sự thay đổi. Người tạo ra CoffeeScript muốn chúng ta code CoffeeScript như là văn viết thông thường. Bảng so sánh giữa Coffee và JavaScript

    CoffeeScript JavaScript
    is ===
    isn't !==
    not !
    and &&
    or ||
    true, yes, on true
    false, no, off false
    @, this this
    of in
    a ** b Math.pow(a, b)
    a // b Math.floor(a / b)
    a %% b (a % b + b)%b
  2. Class, Inheritance, and super

    CoffeeScript có định nghĩa một hàm là hàm constructor, nó sẽ được gọi khi tạo ra một đối tượng của class. Hàm constructor tương tự như các hàm khác trong class, chỉ có điều là nó được gọi một cách tự động khi khởi tạo đối tượng mới của class mà không cần gọi tường minh

    class Animal
        constructor: (@name) ->
        move: (meters) ->
            alert @name + " moved #{meters}m."
    var Animal;
    Animal = (function() {
        function Animal() {}
        return Animal;
    })();
    ({
        constructor: function(name) {
          this.name = name;
        },
        move: function(meters) {
          return alert(this.name + (" moved " + meters + "m."));
        }
    });
Trong CoffeeScript cũng có sự thừa kế như bất cứ một ngôn ngữ hướng đối tượng nào khác.
    class Animal
        constructor: (@name) ->
        move: (meters) ->
            alert @name + " moved #{meters}m."
    class Snake extends Animal
        move: ->
            alert "Slithering..."
            super 5
    sam = new Snake "Sammy the Python"
    sam.move()
    var Animal, Snake, sam,
        __hasProp = {}.hasOwnProperty,
        __extends = function(child, parent) {
            for (var key in parent) {
                if (__hasProp.call(parent, key)) child[key] = parent[key];
            }
            function ctor() {
                this.constructor = child;
            }
            ctor.prototype = parent.prototype;
            child.prototype = new ctor();
            child.__super__ = parent.prototype;
            return child;
       };
    Animal = (function() {
        function Animal(name) {
            this.name = name;
            }
        Animal.prototype.move = function(meters) {
          return alert(this.name + (" moved " + meters + "m."));
        };
        return Animal;
    })();
    Snake = (function(_super) {
        __extends(Snake, _super);
        function Snake() {
          return Snake.__super__.constructor.apply(this, arguments);
        }
        Snake.prototype.move = function() {
          alert("Slithering...");
          return Snake.__super__.move.call(this, 5);
        };
        return Snake;
    })(Animal);
    sam = new Snake("Sammy the Python");
    sam.move();
  1. Function binding
    Account = (customer, cart) ->
        @customer = customer
        @cart = cart
    $('.shopping_cart').bind 'click', (event) ->
        @customer.purchase @cart
    var Account;

      Account = function(customer, cart) {
        this.customer = customer;
        return this.cart = cart;
      };

      $('.shopping_cart').bind('click', (function(_this) {
        return function(event) {
          return _this.customer.purchase(_this.cart);
        };
      })(this));
  1. Try/Catch/Finally
    try
        allHellBreaksLoose()
        catsAndDogsLivingTogether()
    catch error
        print error
    finally
        cleanUp()
    var error;
    try {
        allHellBreaksLoose();
        catsAndDogsLivingTogether();
    } catch (_error) {
        error = _error;
        print(error);
    } finally {
        cleanUp();
    }

Trên đây là căn bản của CoffeeScript mà tôi tìm hiểu được. Nhưng CoffeeScript không chỉ dừng lại ở đó, bạn có thể tìm hiểu thêm tại trang coffeescript.org .


All Rights Reserved