Giới thiệu cuốn Maintainable Javascript 1

1.Căn lề

Khi coder không căn lề hoặc căn lề tùy ý sẽ dẫn đến code rất khó nhìn Ví dụ không tốt

if (wl && wl.length) {
          for (i = 0, l = wl.length; i < l; ++i) {
        p = wl[i];
        type = Y.Lang.type(r[p]);
        if (s.hasOwnProperty(p)) { if (merge && type == 'object') {
      Y.mix(r[p], s[p]);
    } else if (ov || !(p in r)) {
            r[p] = s[p];
          }
        }
      }
    }

Ví dụ tốt

if (wl && wl.length) {
  for (i = 0, l = wl.length; i < l; ++i) {
    p = wl[i];
    type = Y.Lang.type(r[p]);
    if (s.hasOwnProperty(p)) {
      if (merge && type == 'object') {
        Y.mix(r[p], s[p]);
      } else if (ov || !(p in r)) {
        r[p] = s[p];
      }
    }
  }
}

1.1 Sử dụng tab để căn lề

Lợi ích:

Đảm bảo logic vì có sự tương ứng 1-1 giữa số lượng ký tự tab và mức lề. Các bộ soạn thảo cho phép cấu hình độ lớn tab khác nhau nên người lập trình có thể tùy chỉnh độ lớn này phù hợp với yêu cầu của mình

Hạn chế:

Các hệ thống biên dịch tab khác nhau nên khi dùng các bộ soạn thảo hoặc hệ thống khác nhau thì nó hiển thị khác nhau.

1.2 Sử dụng khoảng trắng để căn lề

Có thể là 2, 4 hoặc 8 khoảng trắng.

**Lợi ích: ** Đồng nhất trên tất cả các hệ thống, bộ soạn thảo.

Hạn chế: Một người dùng có thể gặp các vấn đề về format vì cấu hình bộ soạn thảo sai.

2. Ký hiệu kết thúc

// Đúng
var name = "Nicholas";
function sayName() {
  alert(name);
}
// Đúng nhưng không khuyến khích
var name = "Nicholas"
function sayName() {
  alert(name)
}
// Code ban đầu
function getData() {
  return
  {
    title: "Maintainable JavaScript",
    author: "Nicholas C. Zakas"
  }
}
// Cách bộ parse hiểu
function getData() {
  return;
  {
    title: "Maintainable JavaScript",
    author: "Nicholas C. Zakas"
  };
}
// Chạy đúng dù không có dấu ;
function getData() {
  return {
    title: "Maintainable JavaScript",
    author: "Nicholas C. Zakas"
  }
}

3. Chiều dài của dòng

Nếu 1 dòng code dài, cần scroll thì người coder sẽ thấy khó thao tác. Nhiều ngôn ngữ sử dụng giới hạn 80 ký tự cho một dòng. Điều này được quy định từ hơn 20 năm trước và vẫn phổ biến ở hiện tại dù ngày nay các bộ biên tập đã mềm dẻo hơn.

4. Ngắt dòng

// Tốt: Ngắt dòng sau toán tử, căn lề 2 mức dòng tiếp theo
callAFunction(document, element, window, "some string value", true, 123,
    navigator);
// Không tốt: Căn lề 1 mức dòng tiếp theo
callAFunction(document, element, window, "some string value", true, 123,
  navigator);
// Không tốt: Ngắt dòng trước toán tử
callAFunction(document, element, window, "some string value", true, 123
    , navigator);

Ở trong ví dụ trên, dấy phảy là toán tử.

5. Dòng trống

Ví dụ không tốt

if (wl && wl.length) {
  for (i = 0, l = wl.length; i < l; ++i) {
    p = wl[i];
    type = Y.Lang.type(r[p]);
    if (s.hasOwnProperty(p)) {
      if (merge && type == 'object') {
        Y.mix(r[p], s[p]);
      } else if (ov || !(p in r)) {
        r[p] = s[p];
      }
    }
  }
}

Ví dụ tốt

if (wl && wl.length) {

  for (i = 0, l = wl.length; i < l; ++i) {
    p = wl[i];
    type = Y.Lang.type(r[p]);

    if (s.hasOwnProperty(p)) {

      if (merge && type == 'object') {
        Y.mix(r[p], s[p]);
      } else if (ov || !(p in r)) {
        r[p] = s[p];
      }
    }
  }
}

Nên thêm dòng:

Giữa các method

Giữa các biến local trong method và dòng lệnh đầu tiên của nó

Trước comment nhiều dòng hay một dòng

Giữa các phần logic khác nhau trong method để dễ đọc.

6. Đặt tên

Nói chung ta nên sử dụng cách đặt tên phù hợp với ngôn ngữ gốc mà bạn đang dùng nên camel case là cách hầu hết các Java coders sử dụng để đặt tên biến và hàm.

6.1 Biến và hàm

// Tốt
var count = 10;
var myName = "Nicholas";
var found = true;
// Không tốt: Dễ nhầm với hàm
var getCount = 10;
var isFound = true;
// Tốt
function getName() {
  return myName;
}
// Tốt
function theName() {
  return myName;
}

6.2 Tên hàm và method

Từ đầu tiên nên là động từ, có các từ thường dùng sau:

can Hàm trả về giá trị boolean

has Hàm trả về giá trị boolean

is Hàm trả về giá trị boolean

get Hàm không trả về giá trị boolean

set Hàm dùng để set giá trị

6.3 Hằng số

Thường dùng ký tự viết hoa

var MAX_COUNT = 10;
var URL = "http://www.nczonline.net/";

6.4. Hàm tạo

Quy tắc đặt tên giống camel case nhưng ký tự đầu viết hoa

// Tốt
function Person(name) {
  this.name = name;
}

Person.prototype.sayName = function() {
  alert(this.name);
};

var me = new Person("Nicholas");

7. Các kiểu

7.1 String

String có thể viết trong dấu ngoặc đơn hoặc ngoặc kép

// Đúng trong JavaScript
var name = "Nicholas says, \"Hi.\"";

// Cũng đúng trong JavaScript
var name = 'Nicholas says, "Hi"';

Khi viết trên nhiều dòng

// Không tốt
var longString = "Here's the story, of a man \
named Brady.";
// Tốt
var longString = "Here's the story, of a man " +
                 "named Brady.";

7.2 Numbers

// Integer
var count = 10;

// Decimal
var price = 10.0;
var price = 10.00;

// Decimal không tốt
var price = 10.;

// Decimal không tốt
var price = .1;

// Không tốt: Được hiểu là Octal (base 8)
var num = 010;

// Hexadecimal (base 16)
var num = 0xA2;

// E-notation
var num = 1e23;

7.3 Null

Null được dùng để:

Khởi tạo 1 biến mà sau đó có thể được gán object

So sánh với giá trị khởi tạo có hay không giá trị object

Để pass một hàm ở đó mong muốn là object

Để return từ một hàm ở đó mong muốn là object Không nên sử dụng null

Kiểm tra một tham số có được cung cấp hay không

Kiểm tra một giá trị chưa được khởi tạo bằng null

// Tốt
var person = null;

// Tốt
function getPerson() {
  if (condition) {
    return new Person("Nicholas");
  } else {
    return null;
  }
}
// Tốt
var person = getPerson();
if (person !== null) {
  doSomething();
}

// Không tốt
var person;
if (person != null) {
  doSomething();
}

// Không tốt
function doSomething(arg1, arg2, arg3, arg4) {
  if (arg4 != null) {
    doSomethingElse();
  }
}

7.4 Undefined

Các giá trị chưa được khởi tạo có giá trị là undefined, mang ý nghĩa nó đang đợi được gán giá trị thực.

// Không tốt
var person;
console.log(person === undefined);
    //true

Undefined thường bị nhầm với typeof trả về string “undefined” cho một giá trị có giá trị là undefined hoặc chưa được định nghĩa

// foo is not declared
var person;
console.log(typeof person);
   //"undefined"
console.log(typeof foo);
       //"undefined"

Để tránh trường hợp này nên khởi tạo 1 biến ban đầu là null

// Tốt
var person = null;
console.log(person === null);
   //true

7.5 Object

Không tốt: Tạo mới 1 instance Obect rồi thêm properties

// Không tốt
var book = new Object();
book.title = "Maintainable JavaScript";
book.author = "Nicholas C. Zakas";

//Tốt
var book = {
  title: "Maintainable JavaScript",
  author: "Nicholas C. Zakas"
};

7.6 Array

//Không tốt
var colors = new Array("red", "green", "blue");
var numbers = new Array(1, 2, 3, 4);

//Tốt
var colors = [ "red", "green", "blue" ];
var numbers = [ 1, 2, 3, 4 ];