Tips for better Javascript code

Hiện nay xu thể xây dựng trang web độc lập giữa back-end và front-end đòi hỏi khối lượng lớn code Javacript. Điều này đòi hỏi các dev mất rất nhiều công sức trong quá trình phát triển cũng như điều hành trang web. Trong bài viết này, tôi xin phép được đưa ra một vài mẹo nhỏ nhằm nâng cao chất lượng code Javascript

1. Tất cả đều là Object

Cũng như các ngôn ngữ khác, Javascript có các dạng data cơ bản như String , Integer, Date ... nhưng sẽ hiệu quả hơn nếu tất cả các biến cũng như các funciton được tổ chức lại thành các Object giúp cho dễ quản lý cũng như thay đổi chức năng về sau này.

Ví dụ

//handle click event
var callBossName = function(){
    var name = "James Bond";
    var isHandsome = true;
    var carNumber = 5;
    if(isHandSome){
        for(var i = 0; i++, i <= carNumber){
            alert("My boss is " + name);
        }
    }
}

//showing car names
var showCarName = function(){
    var carName = ["BMW", "Ferrari", "Bently", "Aston Martin", "Rolls Royce"]
    alert( carName.join(" - "));
}

Đoạn code trên có đặc điểm là các hàm cũng như các biến được khai báo và sử dụng rất lẻ tẻ, khó tận dụng trong trương lai Chúng ta có có thể refactor thành như sau:

$(function(){
    var carProperties = {
        names: ["BMW", "Ferrari", "Bently", "Aston Martin", "Rolls Royce"],
        boss: {
            name: "James Bond",
            isHandsome: true
        }
    }

    var carFunctions = {
        callBossName: function(){
            if(varProperties.boss.isHandsome){
                for(var i = 0; i++, i <= carProperites.names.length){
                    alert("My boss is " + carProperties.boss.name);
                }
            }
        },
        showCarName: function(){
            alert( carProperties.names.join(" - "));
        }
    }
});

Gom tất cả các biến cũng với các function thành các Object giúp cho việc quản lý cũng nâng cấp sẽ dễ dàng hơn nhiều, đặc biệt khi cần thay đổi một chức năng nào đó

2. Sử dụng Closures

Closure là một trong những kĩ thuật khá là hay của Javascrip. Khi đọc các tài liệu về Closures từ W3C hay Mozilla, người đọc thường bị choánh váng bởi các định nghĩ phức tạp về scope cũng như variable. Đởn giản mà nói, clousures là một cách viết để hàm trả về giá trị là một hàm khác Dưới đây là ví dụ được dưa ra trên W3C

var add = (function () {
    var counter = 0;
    return function () {return counter += 1;}
})();

add();
add();
add();

// the counter is now 3

Ta có thể thấy được từ ví dụ trên, hàm add() thay vì trả về một giá trị cụ thể đã trả ra môt hàm khác thực hiện quá trình tăng giá trị. Sẽ có nhiều người cho rằng sử dụng closure sẽ khiến cho code trở nên hết sức phức tạp và khó quản lý, tuy nhiên sử dụng kỹ thuật này sẽ hạn chế được rất nhiều việc lặp code, đặc biệt trong các hàm sử dụng callback. Dưới đây, tôi xin đưa ra một ví dụ cụ thể về Closures trong ajax callback

Closure trong ajax callback

Thông thường, trong Javascript, đa phần chúng ta sẽ sử dụng Ajax như sau:

$.ajax({
  url: "/categories",
  type: "POST",
  dataType: "json"
}).success(function(data) {
  //handle data success
}).error(function(data) {
  //handle errors
});

Có một đặc điểm thường thấy ở các website xây dựng dựa trên API là một API thường sẽ được gọi nhiều lần nhưng với việc triển khai ajax như trên khiến cho chũng ta phải lặp lại mỗi lần gọi ajax. Khi sử dụng Closures, chúng ta có thể độc lập callback function với ajax call. Dưới đây là một ví dụ cơ bản của sử dụng closures trong ajax call

$(function(){
    var getCategories = function(callback){
        $.ajax({
            url: "/categories",
            type: "POST",
            dataType: "json"
        }).success(function(data){
            callback.handleSuccess(data);
        ).error(function(data){
            callback.handleError(data);
        });
    };

    var displayCategories = function(){
        this.handlSuccess = function(data){
            if(data){
                $("#categories").html(data.categoriesName);
            }
        }
        this.handleError = function(data){
            alert("System error" + data.code);
        }
    };

    getCategories(displayCategories);
});

Như vậy chúng ta đã chia thành 2 phần riêng biệt: ajaxcallback. Trong tương lai chúng ta hoàn toàn có thể sử dụng lại hàm ajax này với hàm callback khác

3. Tổ chức Javascript code

Sau quá trình làm việc với một số project, có rất nheieuf người phàn nàn về sự lộn xộn của code javascript gây khó khăn cho việc maitain cũng như upgrade. Điều này một phần do việc chúng ta chưa biết cách tổ chức cho code Javascript. Chúng ta nên tổ chức code Javascript theo từng chức năng để dễ quản lý. Dưới đây là hình mẫu cấu trúc thư mục:

app/assets/javascripts/
├── application.js
├── application_search.js
├── common
│   ├── calculations.js
│   ├── compatibility.js
│   └── extra_function.js
├── lib
│   ├── angular.min.js
│   ├── bootstrap-affix.js
│   ├── bootstrap-datepicker.js
│   ├── bootstrap-dropdown.js
│   ├── bootstrap-modal.js
│   ├── bootstrap-popover.js
│   ├── bootstrap-tab.js
│   ├── bootstrap-tooltip.js
│   ├── bootstrap-transition.js
│   ├── bootstrap-typeahead.js
│   ├── jquery.cookie.js
│   ├── jquery.fixHeight.js
│   ├── jquery.textchange.js
│   ├── lazyload.min.js
│   └── chat.js
├── messages
│   ├── messages_details.js
│   └── messages_list.js
├── search
│   ├── search.js
│   └── search_filter.js
├── home
│   └── main.js
└── user
    ├── address.js
    └── avaiable_status.js

Ngoài sắp xếp code theo các chức năng, chúng ta nên thêm vào trong đó các thư mục bao gôm:

  • common: lưu trữ các hàm cũng như các biến global cần thiết cho cả trang web
  • lib: lưu trữ các thư viện cần thiết cho trang web như jQuery, AngularJS, bootstrap...

4 Don't repeat yourself - DRY

Dev chắc ai cũng đã từng nghe tới cụm từ này. Tuy nhiên trong khi thực hiện project, không phải lúc nào chúng ta cũng co thể tuân theo được quy tắc này. Dưới đây là hai công cụ khá hữu ích để kiểm tra số lượng code lặp: * Jsinspect * Harukizaemon

Sử dụng hai công cụ này, chúng ta có thể kiểm tra số lượng code lặp trong cả project, từ đó có thể đưa ra giải pháp để có thể refactoring hiệu quả nhất. Tất nhiên, refactoring không bao giờ là điều mà bất cứ programmer nào mong muốn cả. Hãy cố gắng viết code để không bao giờ phải refactoring