Hạn chế lạm dụng If-Else trong JavaScript

11 tháng 9, 2021 By DEVERA ACADEMY

Việc xây dựng các điều kiện phức tạp trong JavaScript với một danh sách dài các câu lệnh if/else hoặc switch luôn tiềm ẩn nhiều khá năng gây lỗi, tạo ra các đoạn code dài ngoằng và trông như một mớ hỗn độn. Thế nên trong bài viết này, chúng ta hãy cùng nhau tìm hiểu một cách làm khác giúp thể hiện các điều kiện tốt hơn.

Khi cần xây dựng nhiều điều kiện, chúng ta có thể sử dụng object literal để code được dễ đọc hơn. Bây giờ, hãy cùng tìm hiểu phương pháp này thông qua ví dụ sau nhé!

Ví dụ: Giả sử chúng ta có một hàm nhận vào một cụm từ "tiếng lóng có vần điệu" và trả về nghĩa của nó.
Khi Sử dụng câu lệnh if / else, nó sẽ giống như sau:

function getTranslation(rhyme) {
if (rhyme.toLowerCase() === "apples and pears") {
return "Stairs";
} else if (rhyme.toLowerCase() === "hampstead heath") {
return "Teeth";
} else if (rhyme.toLowerCase() === "loaf of bread") {
return "Head";
} else if (rhyme.toLowerCase() === "pork pies") {
return "Lies";
} else if (rhyme.toLowerCase() === "whistle and flute") {
return "Suit";
}
return "Rhyme not found";
}

Trông có vẻ không ổn lắm nhỉ? Nó chẳng những không dễ đọc mà còn lặp lại hàm toLowerCase() cho mọi câu lệnh.

Chúng ta có thể tránh sự lặp lại đó bằng cách gán các vần đã được viết thường với toLowerCase() cho một biến và sử dụng câu lệnh switch, giống như sau:

function getTranslation(rhyme) {
switch (rhyme.toLowerCase()) {
case "apples and pears":
return "Stairs";
case "hampstead heath":
return "Teeth";
case "loaf of bread":
return "Head";
case "pork pies":
return "Lies";
case "whistle and flute":
return "Suit";
default:
return "Rhyme not found";
}
}

Bây giờ, chúng ta chỉ gọi toLowerCase() một lần duy nhất, nhưng nó vẫn còn chưa gọn gàng lắm. Hơn nữa câu lệnh switch rất dễ gặp lỗi, trong các trường hợp với nhiều function phức tạp hơn, hoặc đơn giản chỉ là do chúng ta quên mất lệnh break.

Phương pháp thay thế

Bạn có thể sử dụng một đối tượng để xây dựng một chức năng tương tự như trên một cách gọn gàng.

function getTranslationMap(rhyme) {
const rhymes = {
"apples and pears": "Stairs",
"hampstead heath": "Teeth",
"loaf of bread": "Head",
"pork pies": "Lies",
"whistle and flute": "Suit",
};
return rhymes[rhyme.toLowerCase()] ?? "Rhyme not found";
}

Chúng ta xây dựng một đối tượng trong đó key là điều kiện và value là phản hồi cho điều kiện tương ứng. Sau đó, chúng ta sử dụng ngoặc vuông([]) để chọn giá trị từ rhyme được truyền vào.

Ở dòng 10 (dòng lệnh return) có sử dụng toán tử nullish coalescing để gán một phản hồi mặc định. Có nghĩa là nếu rhyme[rhyme.toLowercase ()] là null hoặc undefined (nhưng không phải false hoặc 0 nhé), thì kết quả trả về là chuỗi mặc định "Rhyme not found"

Complex Logic

Chúng ta có thể thực hiện một số logic phức tạp hơn bằng cách truyền một hàm làm vào trong đối tượng thông qua cặp key-value:

function calculate(num1, num2, action) {
const actions = {
add: (a, b) => a + b,
subtract: (a, b) => a - b,
multiply: (a, b) => a * b,
divide: (a, b) => a / b,
};
return actions[action]?.(num1, num2) ?? "Calculation is not recognised";
}

Với cách xây dựng này chúng ta được phép chọn phép tính muốn thực hiện, truyền hai tham số và sau đó nhận kết quả trả về. Ở câu lệnh return có sử dụng toán tử optional chaining (dấu ?. ) với mục đích chỉ cho phép thực thi và phản hồi khi giá trị trả về nếu được xác định, ngược lại chương trình sẽ trả về chuỗi mặc định  "Calculation is not recognised".

Khi xây dựng một loạt các logic phức tạp về câu điều kiện, đừng cố chấp với if/else hay switch, đôi khi chúng ta nên thử một cách nào đó mới mẻ hơn - object trong bài viết này là một ví dụ. Hãy cân nhắc và lựa chọn phương pháp hiệu quả hơn cho các trường hợp xây dựng câu điều kiện nhé! Happy coding!

Tác giả: Jack Taylor

Dịch bởi Devera Academy