Các cách Để Viết Điều Kiện JavaScript Hiệu Quả

 Các cách Để Viết Điều Kiện JavaScript Hiệu Quả

Trong bài viết hôm nay, chúng ta sẽ cùng nhau đi sâu vào các kỹ thuật viết điều kiện sao cho hiệu quả hơn thông qua việc hiểu rõ cấu trúc các câu lệnh điều kiện cho đến việc áp dụng các phương pháp hiện đại như sử dụng mảng, object lookup, destructuring… Nào bây giờ chúng ta hãy cùng nhau đi vào tìm hiểu nhé!

Các Cấu Trúc Điều Kiện Cơ Bản

Câu Lệnh if, else if, else

Câu lệnh if là cấu trúc cơ bản để kiểm tra một điều kiện nào đó. Nếu điều kiện đúng, đoạn mã trong khối if sẽ được thực thi, nếu không, ta có thể sử dụng else hoặc else if để xử lý các trường hợp khác nhau.

// Ví dụ đơn giản với tên khách hàng
const tenKhachHang = "Nguyễn Văn A";
if (tenKhachHang === "Nguyễn Văn A") {
  console.log("Chào mừng anh Nguyễn Văn A!");
} else {
  console.log("Chào mừng quý khách!");
}

Đối với các điều kiện phức tạp hơn, bạn có thể dùng else if để kiểm tra nhiều trường hợp liên tiếp:

const diemTrungBinh = 8.5;
if (diemTrungBinh >= 9) {
  console.log("Xếp loại xuất sắc");
} else if (diemTrungBinh >= 8) {
  console.log("Xếp loại giỏi");
} else if (diemTrungBinh >= 7) {
  console.log("Xếp loại khá");
} else {
  console.log("Cần cố gắng hơn");
}

Toán Tử Ba Ngôi (Ternary Operator)

Toán tử ba ngôi cho phép viết điều kiện ngắn gọn dưới dạng một biểu thức:

javascriptSao chépChỉnh sửaconst soLuong = 10;
const thongBao = soLuong > 0 ? "Còn hàng" : "Hết hàng";
console.log(thongBao);

Biểu thức trên giúp bạn viết mã một cách súc tích, rất hữu ích trong các trường hợp đơn giản.

Switch-case

Cấu trúc switch-case thường được sử dụng khi cần so sánh một giá trị với nhiều trường hợp khác nhau.

const thu = "Thứ Hai";
switch (thu) {
  case "Thứ Hai":
    console.log("Bắt đầu tuần mới!");
    break;
  case "Thứ Ba":
    console.log("Ngày thứ ba làm việc chăm chỉ!");
    break;
  case "Thứ Tư":
    console.log("Giữa tuần rồi!");
    break;
  default:
    console.log("Chào mừng bạn đến với tuần làm việc!");
}

Các Vấn Đề Khi Viết Điều Kiện Trong JavaScript

Vấn Đề về Readability và Maintainability

Một trong những vấn đề phổ biến khi viết điều kiện là mã trở nên không nhất quán, khó đọc và khó bảo trì. Khi số lượng điều kiện tăng lên thì việc theo dõi luồng logic trong đoạn mã của bạn có thể trở nên phức tạp, dẫn đến lỗi khi bảo trì hoặc mở rộng ứng dụng.
Một số dấu hiệu cho thấy mã điều kiện của bạn cần được phải tối ưu lại:

  • Nhiều lần lặp lại logic kiểm tra.
  • Sử dụng nhiều câu lệnh lồng nhau (nested if-else) làm cho mã trở nên khó theo dõi.
  • Việc thêm hoặc sửa đổi các điều kiện trở nên rủi ro vì phải điều chỉnh nhiều phần của mã.

Nested Conditions – Lồng Điều Kiện Quá Sâu

Khi điều kiện được lồng quá sâu, mã nguồn không chỉ khó đọc mà còn dễ dẫn đến lỗi logic. Ví dụ:

const tenKhachHang = "Trần Thị B";
const soLuongDonHang = 5;

if (soLuongDonHang > 0) {
  if (tenKhachHang === "Trần Thị B") {
    console.log("Khách hàng thân thiết");
  } else {
    console.log("Khách hàng mới");
  }
} else {
  console.log("Không có đơn hàng nào");
}

Mặc dù đoạn mã trên hoạt động, nhưng việc lồng điều kiện khiến mã trở nên phức tạp hơn cần thiết. Một cách tiếp cận tốt hơn là sử dụng “early return” (trả về sớm) để giảm bớt sự lồng ghép không cần thiết.

Kỹ Thuật Viết Điều Kiện Hiệu Quả Hơn

Trong phần này, chúng ta sẽ đi vào chi tiết các kỹ thuật giúp bạn viết điều kiện một cách hiệu quả hơn.

Sử Dụng Mảng và Phương Thức includes()

Giả sử bạn cần kiểm tra xem một giá trị có nằm trong một tập hợp các giá trị hợp lệ hay không. Thay vì viết nhiều điều kiện bằng if hoặc switch-case, bạn có thể khai báo một mảng chứa các giá trị hợp lệ và sử dụng phương thức includes() để kiểm tra.

Ví dụ:

Giả sử bạn đang xây dựng một hệ thống bỏ phiếu cho sản phẩm của cửa hàng thực phẩm địa phương. Các màu sắc hợp lệ có thể là: “đỏ”, “cam”, “vàng”, “xanh lá”, “xanh dương”, “tím”. Bạn có thể viết:

const mauHopLe = ["đỏ", "cam", "vàng", "xanh lá", "xanh dương", "tím"];

const boPhieu = (mau) => {
  if (!mauHopLe.includes(mau)) {
    return "Màu không hợp lệ";
  }
  return "Màu hợp lệ";
}

console.log(boPhieu("đỏ"));         // "Màu hợp lệ"
console.log(boPhieu("hồng"));        // "Màu không hợp lệ"

Cách viết này không chỉ giúp mã nguồn trở nên ngắn gọn mà còn dễ dàng mở rộng khi cần thêm màu mới.

Giảm Thiểu Lồng Điều Kiện Bằng Early Return

Early return là một kỹ thuật trong đó bạn kiểm tra điều kiện và trả về kết quả ngay khi điều kiện không thỏa mãn, giúp giảm bớt việc lồng ghép nhiều điều kiện.

Ví dụ:

Thay vì lồng các câu lệnh if như sau:

const kiemTraDonHang = (tenKhachHang, soLuong) => {
  if (soLuong > 0) {
    if (tenKhachHang.length <= 15) {
      return "Đơn hàng hợp lệ";
    } else {
      return "Tên khách hàng quá dài";
    }
  } else {
    return "Không có đơn hàng";
  }
}

Bạn có thể viết lại bằng early return:

javascriptSao chépChỉnh sửaconst kiemTraDonHang = (tenKhachHang, soLuong) => {
  if (soLuong <= 0) return "Không có đơn hàng";
  if (tenKhachHang.length > 15) return "Tên khách hàng quá dài";
  return "Đơn hàng hợp lệ";
}

Cách viết này giúp mã nguồn dễ đọc và dễ bảo trì hơn rất nhiều.

Sử Dụng Object Lookup Thay Vì Switch-case

Đối với những trường hợp mà bạn có nhiều lựa chọn cần kiểm tra và thực thi hành động tương ứng, thay vì dùng switch-case, bạn có thể sử dụng một object. Điều này giúp giảm thiểu mã lặp và tăng tốc độ xử lý.

Ví dụ:

Giả sử bạn có một ứng dụng quản lý đơn hàng và muốn in ra thông báo dựa trên trạng thái đơn hàng:

const trangThaiDonHang = {
  "cho_xu_ly": "Đơn hàng đang chờ xử lý",
  "dang_giao": "Đơn hàng đang được giao",
  "da_giao": "Đơn hàng đã được giao",
  "da_huy": "Đơn hàng đã bị hủy"
};

const thongBaoDonHang = (trangThai) => {
  return trangThaiDonHang[trangThai] || "Trạng thái không xác định";
}

console.log(thongBaoDonHang("dang_giao")); // "Đơn hàng đang được giao"
console.log(thongBaoDonHang("khong_xac_dinh")); // "Trạng thái không xác định"

Cách viết này giúp bạn dễ dàng mở rộng với nhiều trạng thái mới mà không cần thay đổi cấu trúc điều kiện phức tạp.

Sử Dụng Destructuring và Default Parameters

Destructuring và default parameters là hai tính năng của JavaScript ES6 giúp cho việc xử lý tham số và đối tượng trở nên ngắn gọn và rõ ràng hơn. Điều này cũng áp dụng được trong việc viết điều kiện.

Ví dụ:

Giả sử bạn cần viết một hàm xử lý thông tin khách hàng:

const xuLyThongTinKhachHang = ({ ten = "Khách hàng ẩn danh", tuoi = 0, thanhVien = false }) => {
  if (!ten || ten.trim() === "") return "Tên không hợp lệ";
  if (tuoi <= 0) return "Tuổi không hợp lệ";
  
  return thanhVien ? `Chào mừng thành viên ${ten}` : `Chào mừng ${ten}`;
}

console.log(xuLyThongTinKhachHang({ ten: "Nguyễn Văn A", tuoi: 30, thanhVien: true }));
// "Chào mừng thành viên Nguyễn Văn A"

Những cải tiến nhỏ như vậy không những làm cho mã nguồn gọn gàng mà còn giúp bạn tránh được nhiều lỗi không đáng có.

Áp Dụng Nguyên Tắc DRY (Don’t Repeat Yourself)

Trong quá trình xử lý điều kiện, bạn có thể dễ dàng rơi vào bẫy lặp lại cùng một logic nhiều lần. Hãy tìm cách trừu tượng hóa chúng thành các hàm chung. Ví dụ, nếu bạn cần kiểm tra xem một chuỗi có rỗng hay không ở nhiều nơi, hãy viết một hàm kiểm tra chung:

const isEmpty = (str) => {
  return !str || str.trim() === "";
}

// Sử dụng
if (isEmpty(tenKhachHang)) {
  return "Tên khách hàng không được để trống.";
}

Việc này giúp giảm thiểu lỗi và đảm bảo rằng khi cần thay đổi logic, bạn chỉ cần thay đổi ở một nơi.

Tối Ưu Hóa Các Trường Hợp Phức Tạp

Khi ứng dụng của bạn có nhiều điều kiện phức tạp, hãy xem xét cách tách các khối logic thành các hàm riêng biệt. Điều này không chỉ giúp mã nguồn sạch sẽ mà còn giúp bạn dễ dàng kiểm thử từng phần riêng lẻ. Ví dụ:

const kiemTraTenKhachHang = (ten) => {
  if (isEmpty(ten)) return false;
  if (ten.length > 20) return false;
  return true;
}

const kiemTraSoLuong = (soLuong) => {
  return typeof soLuong === "number" && soLuong > 0 && Number.isInteger(soLuong);
}

const kiemTraSanPham = (sanPham, danhSach) => {
  return danhSach.includes(sanPham);
}

// Sử dụng trong hàm chính
const kiemTraDonHang = ({ tenKhachHang, soLuong, sanPham }) => {
  if (!kiemTraTenKhachHang(tenKhachHang)) return "Tên khách hàng không hợp lệ.";
  if (!kiemTraSoLuong(soLuong)) return "Số lượng không hợp lệ.";
  if (!kiemTraSanPham(sanPham, sanPhamHopLe)) return `Sản phẩm '${sanPham}' không hợp lệ.`;
  return "Đơn hàng hợp lệ!";
}

So Sánh Giữa Các Phương Pháp Viết Điều Kiện

Trong quá trình phát triển ứng dụng, việc lựa chọn cấu trúc điều kiện phù hợp là rất quan trọng. Dưới đây là một số so sánh giữa các phương pháp phổ biến:

if-else vs. switch-case

  • if-else:
    • Ưu điểm: Linh hoạt, dễ xử lý nhiều điều kiện phức tạp và kiểm tra nhiều biểu thức.
    • Nhược điểm: Khi số lượng điều kiện lớn, có thể dẫn đến nhiều lần lặp lại và mã lồng sâu.
  • switch-case:
    • Ưu điểm: Phù hợp với các trường hợp cần so sánh một giá trị với nhiều hằng số.
    • Nhược điểm: Khi cần thêm điều kiện phức tạp hay nhiều trường hợp có hành động tương tự nhau, switch-case trở nên rườm rà và khó mở rộng.

Mảng vs. Object Lookup

  • Mảng và includes():
    • Thích hợp cho việc kiểm tra sự tồn tại của một giá trị trong tập hợp các giá trị hợp lệ.
    • Cách sử dụng đơn giản, dễ mở rộng khi cần thêm hoặc bớt các phần tử.
  • Object Lookup:
    • Hữu ích khi cần ánh xạ một giá trị tới một hành động cụ thể, giúp tránh việc lặp lại các câu lệnh if hay switch-case.
    • Tốc độ truy xuất nhanh hơn và mã nguồn gọn gàng hơn.

Kết Luận

Hy vọng rằng bài viết này đã cung cấp cho bạn những kiến thức bổ ích và những gợi ý thực tiễn để bạn có thể cải thiện cách viết điều kiện trong dự án của mình. Chúc bạn thành công nhé!

Thái Viết Nhật

Mình muốn chia sẻ đam mê về công nghệ và phát triển bản thân đến với mọi người

Bài Viết Liên Quan