Làm sao để code javascript tốt hơn?


Chào mọi người,hôm nay mình sẽ trình bày về Best practice trong javascript,tức là các quy tắc được các lập trình viên đi trước đúc kết ra sau khi họ đã làm việc rất lâu với javascript.Như chúng ta đã biết,javascript là ngôn ngữ khá dễ học nhưng để master nó thì không phải vấn đề đơn giản.Bất kỳ lập trình viên web nào đều có thể sử dụng JS một cách thuần thục,tuy vậy trong JS lại ẩn chứa rất nhiều thứ rất là loằng ngoằng nhiều khi lập trình viên lâu năm cũng đau đầu vì không rõ bug sinh ra do đâu.Vì vậy bài viết này viết ra mong góp một phần nhỏ giúp các bạn hiểu hơn về JS và làm việc với nó trở nên vui vẻ hơn.Trong bài này mình sẽ sử dụng bản JS phiên bản ES5,vì từ 2015 trở đi JS update phiên bản lên ES6..,bản chất vẫn là JS nhưng mở rộng thêm và tối ưu code và khắc phục các nhược điểm của  ES5.

1.Tránh sử dụng biến toàn cục(global variables)
Tránh sử dụng biến toàn cục(global),thay vào đó nên sử dụng biến cục bộ(local),điều này áp dụng cho tất cả kiểu dữ liệu,đối tượng(object) và function.Bởi vì biến,function toàn cục sẽ bị ghi đè bởi bất kỳ đoạn script nào khác và việc đó chúng ta sẽ không cover được.Để giải quyết vấn đề này các bạn nên học cách sử dụng Closures .
ví dụ
 var a = 10;  
 function demo(){  
  a = 100+1;  
  console.log(a); 
 }
 demo();// kết quả là 101
 console.log(a);  // kết quả là 101

Chúng ta khai báo biến a là biến toàn cục và trong hàm demo đổi giá trị nó thành 101,sau khi chạy hàm demo() thì giá trị của biến a đã thay đổi.Đến lúc nào đó một function bất kỳ sử dụng lại biến a sẽ nhận được giá trị sai lệch.

2.Luôn luôn khai báo biến cục bộ trong function
Trong JS nếu khai báo biến trong function thì nó là biến cục bộ,giả sử có một biến toàn cục trùng với tên với nó thì cũng không ảnh hưởng đến giá trị biến mà chúng ta khai báo trong function.
Note: Các biến cục bộ phải khai báo bằng từ khóa var,nếu không biến đó sẽ được hiểu là biến toàn cục
ví dụ

 var a = 10;  
 function test(){  
   var a = 11;  
   console.log(a); 
 } 
 function demo(){
   b = 20; // đây là biến toàn cục đấy nhé
   console.log(b);
 }
 test();  // kết quả là 11
 console.log(a);  //kết quả là 10
 demo(); //kết quả là 20
 console.log(b); //kết quả cũng là 20


biến a trong function test và biến a toàn cục là 2 biến khác nhau.Biến b trong function demo() nhưng nó sẽ sử dụng được khắp mọi nơi vì nó là biến toàn cục.

3.Luôn khai báo các biến lên đầu.
Tạo thói quen đặt các khai báo ở đầu mỗi script hoặc function.Điều này:

 - Giúp code sáng hơn (clean code)  
 - Cung cấp một nơi duy nhất để tìm kiếm các biến,có khi nào các bạn không hiểu biến này được 
   khai báo ở đâu và loay hoay tìm nó trong cả đoạn code dài như tờ sớ :D  
 - Giúp tránh các biến toàn cục không mong muốn  
 - Giúp tránh việc khai báo đi khai báo lại một biến.  

ví dụ

 //khai báo ngay từ đầu
var firstName, lastName, price, discount, fullPrice;
 //sau đó sử dụng 
 firstName = "John";  
 lastName = "Doe";  
 price = 19.90;  
 discount = 0.10;  
 fullPrice = price * 100 / discount;  

Mặc định JS cũng đưa tất cả các khai báo lên trên cùng(javascript hoisting).

4.Khởi tạo các biến
JS khuyến khích sau khi khai báo biến thì cũng nên khởi tạo giá trị mặc định cho biến.

- giúp tạo code sạch hơn(clean code)  
- cung cấp một nơi duy nhất để khởi tạo biến  
- tránh các giá trị undefined.  

ví dụ

 var firstName = "",  
   lastName = "",  
   price = 0,  
   discount = 0,  
   fullPrice = 0,  
   myArray = [],  
   myObject = {};  

Vì JS không ràng buộc kiểu dữ liệu của biến nên khi khởi tạo cũng là cung cấp cách sử dụng biến.

5.Không bao giờ khai báo Number,String, hoặc Boolean Object
Luôn coi number,string hoặc boolean là kiểu dữ liệu nguyên thủy.Không phải là đối tượng.Khai báo đối tượng làm chậm tốc độ thực thi và các lỗi khó chịu
ví dụ:
 var x = new String("John");         
 var y = new String("John");  
 (x == y)// kết quả là false vì không thể so sánh 2 object với nhau được,mỗi obj là một địa 
chỉ ô nhớ khác nhau.

6.Không sử dụng new Object()
Tất cả kiểu dữ liệu nên được dùng là kiểu dữ liệu nguyên thủy.

 - sử dụng {} thay cho new Object()  
 - sử dụng "" thay cho new String()  
 - sử dụng 0 thay cho new Number()  
 - sử dụng false thay cho new Boolean()  
 - sử dung [] thay cho new Array()  
 - sử dụng /()/ thay cho new RegExp()  
 - sử dụng function(){} thay cho new Function()  

ví dụ

 var x1 = {};      // new object  
 var x2 = "";      // new primitive string  
 var x3 = 0;      // new primitive number  
 var x4 = false;    // new primitive boolean  
 var x5 = [];      // new array object  
 var x6 = /()/;     // new regexp object  
 var x7 = function(){}; // new function object  

7.Cẩn thận với việc chuyển đổi kiểu tự động
JS quản lý kiểu dữ liệu khá lỏng lẻo.Một biết có thể chứa các kiểu dữ liệu khác nhau và một biến có thể thay đổi kiểu dữ liệu của nó.

 var x = "Hello";   // kiểu của x là string  
 x = 5;        // thay đổi kiểu của x thành number  

Khi thực hiện các phép toán JS có thể thực hiện chuyển đổi qua lại giữa số và chuỗi và ngược lại

 var x = 5 + 7;    // x.valueOf() is 12, typeof x is a number  
 var x = 5 + "7";   // x.valueOf() is "57", typeof x is a string  
 var x = "5" + 7;   // x.valueOf() is "57", typeof x is a string  
 var x = 5 - 7;    // x.valueOf() is -2, typeof x is a number  
 var x = 5 - "7";   // x.valueOf() is -2, typeof x is a number  
 var x = "5" - 7;   // x.valueOf() is -2, typeof x is a number  
 var x = 5 - "x";   // x.valueOf() is NaN, typeof x is a number 
 var x = "abcd" - "cde" // x.valueOf() is NaN, typeof is a number

trừ một chuỗi cho một chuỗi,không tạo ra lỗi nhưng kết quả là NaN(Not a Number).Vì vậy mỗi khi thực hiện các phép toán với 2 kiểu dữ liệu khác nhau,tốt nhất nên chuyển chúng thành cùng 1 định dạng rồi mới thực hiện phép toán.

8.Sử dụng === để so sánh
Toán tử  == luôn chuyển đổi để phù hợp giữa các kiểu dữ liệu trước khi so sánh
Toán tử  === so sánh các giá trị và kiểu dữ liệu
ví dụ:

 0 == ""; // js sẽ convert 0 và "" về thành một kiểu và thực hiện so sánh nên sẽ cho kết quả true
 1 == "1"; // true  
 1 == true;// true  
 0 === ""; // false  
 1 === "1";// false  
 1 === true;// false  

9.Sử dụng tham số mặc định
Giả  sử một function có 1 tham số,sau đó function đó được gọi nhưng thiếu tham số truyền vào.Điều này có thể phá vỡ code của chúng ta.Thay vì đó nên set giá trị của đối số truyền vào là undefined.
ví dụ:

 function myFunction(y) {  
   if (y === undefined) {  
     y = 0;  
   }  
 }  

Đọc thêm về tham số và đối số tại đây

10.Kết thúc Switches với Defaults

Luôn luôn kết thúc câu lênh swich với default ngay cả khi bạn nghĩ nó không cần thiết(vì bạn cứ tưởng đã cover hết tất cả trường hợp).
ví dụ:

 switch (new Date().getDay()) {  
   case 0:  
     day = "Sunday";  
     break;  
   case 1:  
     day = "Monday";  
     break;  
   case 2:  
     day = "Tuesday";  
     break;  
   case 3:  
     day = "Wednesday";  
     break;  
   case 4:  
     day = "Thursday";  
     break;  
   case 5:  
     day = "Friday";  
     break;  
   case 6:  
     day = "Saturday";  
     break;  
   default:  
     day = "Unknown";  
 }  

11.Tránh sử dụng hàm eval()
Hàm eval() sử dụng để chạy code js dưới dạng text,trong hầu hết các trường hợp không cần thiết phải sử dụng nó.Bởi vì cho phép một mã bất kỳ được chạy cũng sẽ ảnh hưởng đến vấn đề bảo mật
ví dụ về eval()

 eval("console.log('demo_eval')");  //kết quả demo_eval được in ra

12.Sử dụng try catch
Có một số trường hợp chúng ta không thể cover hết được các giá trị truyền vào từ phía client,việc đó có thể phá vỡ và làm code của chúng ta bị chết.Vì vậy nên try catch để xử lý và bỏ qua các giá trị gây lỗi và tiếp tục chạy code.


Nhận xét

Bài đăng phổ biến từ blog này

Cài đặt SSL cho website sử dụng certbot

Xây dựng một hệ thống comment real-time hoặc chat đơn giản sử dụng Pusher

CÁC BÀI TẬP SQL CƠ BẢN - PART 1

Xây dựng một hệ thống tracking hành vi người dùng (phần 1)

Xây dựng một hệ thống tracking hành vi người dùng (phần 2)

Enterprise architecture trên 1 tờ A4

Web caching (P2)

Bàn về async/await trong vòng lặp javascript

Web caching (P1)

Cài đặt môi trường để code website Rails