Chào bạn! Trong thế giới phát triển web hiện đại, JavaScript đóng vai trò then chốt trong việc tạo ra các ứng dụng web động và tương tác. Tuy nhiên, việc viết mã JavaScript sạch và dễ bảo trì không phải lúc nào cũng dễ dàng. Bài viết này codetuthub sẽ trình bày các "Best Practices" giúp bạn viết mã JavaScript sạch, dễ đọc và hiệu quả hơn. Viết mã JavaScript sạch giúp dễ bảo trì, cải thiện hiệu suất và tránh lỗi trong quá trình phát triển. Dưới đây là những thực hành tốt nhất mà bạn nên áp dụng để viết mã JavaScript chuyên nghiệp hơn:

1. Sử dụng letconst thay vì var

Trong ES6, letconst được giới thiệu để thay thế var. Chúng giúp tránh các lỗi liên quan đến phạm vi biếnhoisting. var có phạm vi là function-scoped, trong khi let và const có phạm vi là block-scoped. Điều này giúp tránh các lỗi không mong muốn do biến bị "rò rỉ" ra ngoài phạm vi dự kiến. const được sử dụng cho các biến không thay đổi giá trị, giúp tăng tính an toàn và dễ hiểu của code.

  • const dùng cho biến không thay đổi.
  • let dùng cho biến có thể thay đổi giá trị.

Ví dụ

js
// Không nên:
var name = "John";

// Nên sử dụng:
let name = "John"; // Có thể thay đổi giá trị
const age = 25; // Không thể thay đổi giá trị

2. Tránh sử dụng biến toàn cục

Biến toàn cục có thể bị thay đổi bất kỳ đâu trong code, gây khó khăn cho việc debug và bảo trì. Biến toàn cục có thể bị ghi đè bởi các phần khác của code, gây ra lỗi khó debug. Thay vào đó, hãy sử dụng module pattern hoặc IIFE (Immediately Invoked Function Expression) để tạo ra các scope riêng biệt.

Giải pháp

  • Sử dụng const hoặc let trong phạm vi cụ thể.
  • Đóng gói biến trong một hàm hoặc module.
js
// Không nên: Biến toàn cục dễ gây lỗi
let userCount = 0;
function incrementUserCount() {
  userCount++;
}

// Nên sử dụng:
function createUserManager() {
  let userCount = 0;
  return function increment() {
    userCount++;
  };
}

3. Sử dụng Arrow function để có cú pháp gọn gàng hơn

Arrow functions có cú pháp ngắn gọn hơn so với function truyền thống, giúp code dễ đọc và dễ hiểu hơn. Đặc biệt hữu ích khi làm việc với các hàm callback. Xem thêm về Arrow function ở bài viết này: So sánh function() và arrow function trong JavaScript).

Ví dụ

js
// Không nên:
const square = function (num) {
  return num * num;
};

// Nên sử dụng:
const square = num => num * num;

Arrow function phù hợp với callback và các phương thức như map, filter, reduce.

4. Sử dụng async/await để xử lý bất đồng bộ

async/await giúp code bất đồng bộ (ví dụ: fetch API) dễ đọc và dễ hiểu hơn. Thay vì sử dụng callback hoặc promise chain, bạn có thể viết code bất đồng bộ như code đồng bộ. Xem thêm về Async/Await.

Ví dụ

js
async function fetchData() {
    try {
        let response = await fetch("https://api.example.com/data");
        let data = await response.json();
        console.log(data);
    } catch (error) {
        console.error("Lỗi xảy ra:", error);
    }
}
fetchData();

5. Sử dụng Strict Mode

Strict mode giúp phát hiện các lỗi tiềm ẩn trong code và ngăn chặn các hành vi không an toàn. Để kích hoạt strict mode, hãy đặt 'use strict'; ở đầu file hoặc trong một function.

Ví dụ

js
'use strict';
let x = 3.14; // Không có lỗi
y = 3.14; // Lỗi: y chưa được khai báo

6. Xử lý lỗi một cách hợp lý

Sử dụng try...catch block để bắt và xử lý lỗi. Điều này giúp ứng dụng không bị crash khi có lỗi xảy ra.

Ví dụ

js
// Không nên: Không xử lý lỗi
const userData = JSON.parse(userResponse);

// Nên sử dụng:
try {
  const userData = JSON.parse(userResponse);
} catch (error) {
  console.error("Lỗi JSON không hợp lệ:", error);
}

7. Tối ưu vòng lặp để cải thiện hiệu suất

Tránh các phép tính toán phức tạp trong vòng lặp, đặc biệt là DOM manipulation. Sử dụng các phương thức như forEach, map, filter khi có thể để tận dụng các tối ưu của engine JavaScript.

Ví dụ

Dùng map, filter, reduce thay vì for nếu có thể:

js
let numbers = [1, 2, 3, 4, 5];
let squared = numbers.map(n => n * n);
console.log(squared);

8. Giảm thiểu thao tác DOM để cải thiện hiệu suất

DOM manipulation là một trong những nguyên nhân gây chậm trễ hiệu suất của ứng dụng web. Hãy cố gắng nhóm các thay đổi DOM lại và thực hiện chúng một lần.

Giải pháp

  • Tránh truy cập DOM nhiều lần trong vòng lặp.
  • Sử dụng Document Fragment để giảm thao tác DOM.
js
let fragment = document.createDocumentFragment();
for (let i = 0; i < 100; i++) {
    let div = document.createElement("div");
    div.textContent = `Item ${i}`;
    fragment.appendChild(div);
}
document.body.appendChild(fragment);

9. Chọn một quy tắc code style và tuân theo

Style Guide giúp code nhất quán và dễ đọc hơn. Một số style guide phổ biến là Airbnb JavaScript Style Guide, Google JavaScript Style Guide.

Ví dụ

Tuân theo các quy tắc của Airbnb JavaScript Style Guide hoặc Prettier.

js
// Không tốt
function sayhello(){console.log("Hello");}
// Tốt
function sayHello() {
    console.log("Hello");
}

10. Sử dụng tên biến và hàm có ý nghĩa

Tên biến và tên hàm nên được đặt sao cho phản ánh đúng mục đích sử dụng của chúng. Tránh sử dụng những tên ngắn gọn, mơ hồ như x, y trừ khi thực sự cần thiết (ví dụ: biến đếm trong vòng lặp).

Ví dụ

js
// Không nên:
let x = 100;
let y = 200;

// Nên sử dụng:
let screenWidth = 100;
let screenHeight = 200;

Việc đặt tên rõ ràng giúp cho code tự giải thích và giảm bớt nhu cầu sử dụng chú thích không cần thiết.

11. Giữ hàm ngắn gọn và tập trung (Single Responsibility Principle)

Mỗi hàm nên thực hiện một nhiệm vụ cụ thể để code dễ kiểm thử, bảo trì và hiểu hơn. Khi mỗi hàm đảm nhiệm một chức năng riêng biệt, bạn có thể thay đổi hoặc sửa lỗi một cách độc lập mà không ảnh hưởng đến các phần khác.

Ví dụ

js
// Không nên: Hàm thực hiện quá nhiều việc
function handleUserProfile(user) {
  console.log(`User: ${user.name}`);
  user.active = true;
  saveToDatabase(user);
  sendEmail(user.email);
}

// Nên chia nhỏ thành các hàm có nhiệm vụ rõ ràng:
function logUser(user) {
  console.log(`User: ${user.name}`);
}

function activateUser(user) {
  user.active = true;
}

function saveUser(user) {
  saveToDatabase(user);
}

function notifyUser(email) {
  sendEmail(email);
}

12. Ưu tiên sử dụng Template Literals cho chuỗi

Template literals (dùng dấu `) giúp kết hợp chuỗi và biến một cách trực quan, tăng khả năng đọc hiểu của code.

Ví dụ

js
// Không nên: Nối chuỗi rườm rà
const greeting = "Hello, " + name + "!";

// Nên sử dụng:
const greeting = `Hello, ${name}!`;

13. Viết code theo Mô-đun (DRY - Don't Repeat Yourself)

Tránh lặp lại code bằng cách trừu tượng hóa các chức năng chung thành các hàm hay module. Điều này giúp giảm thiểu lỗi và tăng tính tái sử dụng.

Ví dụ

js
// Không nên: Lặp lại logic tương tự
function getAdminDashboard() {
  return { userType: "admin", access: "full" };
}

function getUserDashboard() {
  return { userType: "user", access: "limited" };
}

// Nên sử dụng:
function getDashboard(userType) {
  const access = userType === "admin" ? "full" : "limited";
  return { userType, access };
}

14. Sử dụng tham số mặc định (Default Parameters)

Đặt giá trị mặc định cho tham số của hàm giúp code trở nên rõ ràng và an toàn hơn, đặc biệt khi không có giá trị nào được truyền vào.

Ví dụ

js
// Không nên: Kiểm tra thủ công tham số
function greet(name) {
  const userName = name || "Guest";
  console.log(`Hello, ${userName}`);
}

// Nên sử dụng:
function greet(name = "Guest") {
  console.log(`Hello, ${name}`);
}

15. Viết Unit Tests

Unit tests giúp đảm bảo rằng các hàm và module hoạt động đúng như mong đợi, phát hiện lỗi sớm và tăng cường sự tin cậy của ứng dụng.

Ví dụ (với Jest)

js
// sum.js
function sum(a, b) {
  return a + b;
}
module.exports = sum;

// sum.test.js
const sum = require('./sum');

test('Cộng 1 + 2 bằng 3', () => {
  expect(sum(1, 2)).toBe(3);
});

16. Sử dụng comment và tài liệu code

Comment giúp giải thích mục đích của code, đặc biệt là những đoạn code phức tạp. Documentation giúp người khác (và cả bạn trong tương lai) hiểu cách sử dụng code của bạn.

Ví dụ

js
/**
 * Tính tổng hai số
 * @param {number} a - Số thứ nhất
 * @param {number} b - Số thứ hai
 * @returns {number} Tổng của hai số
 */
function sum(a, b) {
    return a + b;
}

17. Giữ số lượng phụ thuộc ngoại (Dependencies) ở mức tối thiểu

Việc sử dụng quá nhiều thư viện bên ngoài có thể làm cho dự án trở nên nặng nề và dễ gặp các lỗ hổng bảo mật. Hãy tận dụng các tính năng có sẵn của JavaScript và chỉ thêm những thư viện thực sự cần thiết.

Lời khuyên

  • Thường xuyên xem xét lại danh sách các dependencies.
  • Ưu tiên sử dụng các giải pháp gọn nhẹ, đã được kiểm chứng về bảo mật.

Kết luận

Việc viết code sạch không chỉ giúp tăng năng suất làm việc mà còn làm cho dự án của bạn trở nên dễ bảo trì và mở rộng trong tương lai. Bằng cách áp dụng những mẹo và kỹ thuật đã được trình bày ở trên, bạn sẽ cải thiện đáng kể chất lượng code cũng như sự hợp tác trong team phát triển. Hãy bắt đầu áp dụng ngay hôm nay để cảm nhận sự khác biệt!

Hy vọng bài viết này sẽ là nguồn tham khảo hữu ích cho các bạn lập trình viên JavaScript. Hãy theo dõi codetuthub.com để cập nhật thêm nhiều bài viết, hướng dẫn và mẹo hay về lập trình. Happy coding!