Bài 4.3: Cấu trúc điều khiển if-else và vòng lặp trong JS

Chào mừng bạn quay trở lại với hành trình chinh phục Lập trình Web Front-end! Sau khi đã làm quen với các khái niệm cơ bản và cách JS tương tác với HTML/CSS, đã đến lúc chúng ta trang bị cho code của mình khả năng ra quyết địnhthực hiện các tác vụ lặp đi lặp lại. Đây chính là lúc cấu trúc điều khiển if-else và các loại vòng lặp tỏa sáng.

Hãy tưởng tượng code của bạn như một "bộ não" hoạt động theo luồng. Ban đầu, luồng chạy theo một đường thẳng từ trên xuống dưới. Nhưng trong thế giới thực, mọi thứ không đơn giản như vậy. Chúng ta cần xử lý các tình huống khác nhau dựa trên điều kiện, hoặc thực hiện một công việc nhiều lần mà không muốn viết đi viết lại cùng một đoạn code. Đó là lý do tại sao chúng ta cần cấu trúc điều khiển.

I. Cấu trúc điều khiển if-else: Khi code "biết suy nghĩ"

Cấu trúc điều khiển cho phép chúng ta thay đổi luồng thực thi mặc định của chương trình. Quan trọng nhất và phổ biến nhất chính là if-else, giúp code của bạn đưa ra quyết định dựa trên một điều kiện.

1. Lệnh if đơn giản

Lệnh if cho phép bạn thực thi một khối code chỉ khi một điều kiện là đúng (true).

Cú pháp cơ bản:

if (điều_kiện) {
  // Khối code này sẽ chạy nếu điều kiện là true
}

Giải thích:

  • điều_kiện: Đây là một biểu thức trả về giá trị boolean (true hoặc false). Ví dụ: x > 10, name === 'Alice', isLoggedIn.
  • { ... }: Đây là khối code sẽ được thực thi nếu điều_kiệntrue. Nếu chỉ có một lệnh duy nhất trong khối, bạn có thể bỏ qua dấu ngoặc nhọn, nhưng việc sử dụng nó luôn được khuyến khích để code rõ ràng và dễ bảo trì hơn.

Ví dụ:

let age = 18;

if (age >= 18) {
  console.log("Bạn đủ tuổi bầu cử.");
}

Hãy phân tích đoạn code trên:

  • Chúng ta khai báo biến age với giá trị là 18.
  • Câu lệnh if (age >= 18) kiểm tra xem age có lớn hơn hoặc bằng 18 hay không.
  • Trong trường hợp này, 18 >= 18true.
  • Vì điều kiện đúng, khối code bên trong {} được thực thi, và dòng chữ "Bạn đủ tuổi bầu cử." sẽ xuất hiện trong console.
2. Lệnh if-else

Thường thì khi một điều kiện không đúng, chúng ta lại muốn thực hiện một hành động khác. Đó là lúc else xuất hiện.

Cú pháp cơ bản:

if (điều_kiện) {
  // Khối code này chạy nếu điều kiện là true
} else {
  // Khối code này chạy nếu điều kiện là false
}

Giải thích:

  • Nếu điều_kiệntrue, khối code trong if sẽ được thực thi.
  • Nếu điều_kiềufalse, khối code trong else sẽ được thực thi.
  • Chỉ một trong hai khối code (if hoặc else) sẽ được chạy.

Ví dụ:

let temperature = 25;

if (temperature > 30) {
  console.log("Trời nóng quá!");
} else {
  console.log("Thời tiết thật dễ chịu.");
}

Hãy phân tích đoạn code trên:

  • Biến temperature là 25.
  • Điều kiện temperature > 30 (25 > 30) là false.
  • Vì điều kiện sai, khối code trong else được thực thi, và dòng "Thời tiết thật dễ chịu." xuất hiện.
3. Lệnh if-else if-else (Xử lý nhiều điều kiện)

Khi bạn có nhiều hơn hai khả năng hoặc nhiều điều kiện cần kiểm tra theo trình tự, bạn sử dụng else if.

Cú pháp cơ bản:

if (điều_kiện_1) {
  // Khối code chạy nếu điều kiện_1 true
} else if (điều_kiện_2) {
  // Khối code chạy nếu điều kiện_1 false VÀ điều_kiện_2 true
} else if (điều_kiện_3) {
  // Khối code chạy nếu điều_kiện_1 false VÀ điều_kiện_2 false VÀ điều_kiện_3 true
} else {
  // Khối code chạy nếu TẤT CẢ các điều kiện trên đều false
}

Giải thích:

  • Hệ thống sẽ kiểm tra các điều kiện tuần tự từ trên xuống dưới.
  • Nó sẽ thực thi khối code của điều kiện đầu tiên mà nó thấy là true.
  • Nếu không có điều kiện nào là true, khối code trong else cuối cùng (nếu có) sẽ được thực thi.
  • Chỉ một khối code duy nhất trong toàn bộ cấu trúc if-else if-else này được chạy.

Ví dụ (Hệ thống xếp loại điểm):

let score = 85;
let grade;

if (score >= 90) {
  grade = 'A';
} else if (score >= 80) {
  grade = 'B'; // score >= 80 VÀ score < 90
} else if (score >= 70) {
  grade = 'C'; // score >= 70 VÀ score < 80
} else {
  grade = 'D'; // score < 70
}

console.log(`Điểm của bạn là: ${score}, xếp loại: ${grade}`);

Hãy phân tích đoạn code trên:

  • score là 85.
  • score >= 90 (85 >= 90) là false.
  • Code nhảy xuống else if (score >= 80). Điều kiện này (85 >= 80) là true.
  • Khối code tương ứng (grade = 'B';) được thực thi.
  • Hệ thống thoát khỏi toàn bộ cấu trúc if-else if-else này và không kiểm tra các điều kiện else if hay else còn lại.
  • Kết quả in ra: "Điểm của bạn là: 85, xếp loại: B".
4. Toán tử Ba ngôi (Ternary Operator) - Cú pháp viết tắt cho if-else đơn giản

Khi bạn chỉ cần gán một giá trị cho một biến dựa trên một điều kiện đơn giản, toán tử ba ngôi cung cấp một cú pháp ngắn gọnthanh lịch hơn.

Cú pháp:

let ketQua = (điều_kiện) ? gia_tri_neu_true : gia_tri_neu_false;

Giải thích:

  • điều_kiện: Biểu thức boolean cần kiểm tra.
  • gia_tri_neu_true: Giá trị sẽ được gán cho ketQua nếu điều_kiệntrue.
  • gia_tri_neu_false: Giá trị sẽ được gán cho ketQua nếu điều_kiệnfalse.

Ví dụ:

let isMember = true;
let shippingFee = isMember ? 0 : 5;

console.log(`Phí vận chuyển: $${shippingFee}`); // Output: Phí vận chuyển: $0

let isLoggedIn = false;
let welcomeMessage = isLoggedIn ? "Chào mừng trở lại!" : "Vui lòng đăng nhập.";

console.log(welcomeMessage); // Output: Vui lòng đăng nhập.

Hãy phân tích đoạn code trên:

  • Ví dụ 1: isMembertrue. Toán tử ba ngôi kiểm tra isMember. Vì nó là true, giá trị đầu tiên sau ? (là 0) được gán cho shippingFee.
  • Ví dụ 2: isLoggedInfalse. Toán tử ba ngôi kiểm tra isLoggedIn. Vì nó là false, giá trị sau : (là "Vui lòng đăng nhập.") được gán cho welcomeMessage.

Toán tử ba ngôi rất hữu ích cho các trường hợp đơn giản, nhưng với logic phức tạp hơn hoặc nhiều lệnh cần thực thi, if-else rõ ràng và dễ đọc hơn.

II. Vòng lặp (Loops): Khi code "biết lặp lại"

Trong lập trình, chúng ta thường cần thực hiện cùng một hành động nhiều lần. Thay vì viết lặp đi lặp lại đoạn code đó, chúng ta sử dụng vòng lặp (loops). Vòng lặp giúp tự động hóa các tác vụ lặp đi lặp lại, tiết kiệm thời gian và làm cho code ngắn gọn hơn.

JavaScript cung cấp một số loại vòng lặp phổ biến.

1. Vòng lặp for

Vòng lặp for là loại vòng lặp được sử dụng phổ biến nhất khi bạn biết trước (hoặc có thể dễ dàng xác định) số lần lặp cần thiết.

Cú pháp:

for (khởi_tạo; điều_kiện; bước_nhảy) {
  // Khối code này sẽ lặp lại
}

Giải thích:

  • khởi_tạo: Thực thi một lần duy nhất khi bắt đầu vòng lặp. Thường dùng để khai báo và khởi tạo biến đếm (ví dụ: let i = 0;).
  • điều_kiện: Kiểm tra trước mỗi lần lặp. Nếu điều kiện là true, vòng lặp tiếp tục. Nếu là false, vòng lặp kết thúc.
  • bước_nhảy: Thực thi sau mỗi lần lặp. Thường dùng để cập nhật biến đếm (ví dụ: i++, j--, k = k + 2).

Ví dụ (In các số từ 1 đến 5):

for (let i = 1; i <= 5; i++) {
  console.log("Số thứ tự: " + i);
}

Hãy phân tích đoạn code trên:

  1. Khởi tạo: let i = 1; - Biến i được tạo và gán giá trị 1.
  2. Kiểm tra điều kiện: i <= 5 (1 <= 5) là true. Vòng lặp bắt đầu.
  3. Thực thi khối code: console.log("Số thứ tự: " + i); - In ra "Số thứ tự: 1".
  4. Bước nhảy: i++ - i tăng lên thành 2.
  5. Kiểm tra điều kiện: i <= 5 (2 <= 5) là true. Tiếp tục.
  6. Thực thi khối code: In ra "Số thứ tự: 2".
  7. Bước nhảy: i++ - i tăng lên thành 3.
  8. ... Quá trình này lặp lại cho đến khi i là 6.
  9. Kiểm tra điều kiện: i <= 5 (6 <= 5) là false. Vòng lặp kết thúc.

Kết quả sẽ là các dòng: "Số thứ tự: 1", "Số thứ tự: 2", "Số thứ tự: 3", "Số thứ tự: 4", "Số thứ tự: 5".

2. Vòng lặp while

Vòng lặp while được sử dụng khi bạn không biết trước số lần lặp, mà chỉ biết rằng vòng lặp sẽ tiếp tục miễn là một điều kiện nào đó còn đúng.

Cú pháp:

while (điều_kiện) {
  // Khối code này sẽ lặp lại miễn là điều_kiện còn true
  // Đảm bảo có lệnh nào đó làm thay đổi điều kiện
}

Giải thích:

  • điều_kiện: Kiểm tra trước mỗi lần lặp. Nếu điều kiện là true, khối code bên trong sẽ được thực thi. Nếu là false, vòng lặp kết thúc.
  • Quan trọng: Bên trong khối code của vòng lặp while, bạn phải có ít nhất một lệnh làm thay đổi điều_kiện để nó cuối cùng trở thành false. Nếu không, bạn sẽ tạo ra một vòng lặp vô hạn (infinite loop), khiến chương trình bị treo.

Ví dụ (Nhân đôi một số cho đến khi lớn hơn 100):

let number = 5;
let count = 0;

while (number <= 100) {
  number = number * 2;
  count++;
  console.log(`Lần lặp ${count}: number = ${number}`);
}

console.log(`Vòng lặp kết thúc. Giá trị cuối cùng của number: ${number}`);

Hãy phân tích đoạn code trên:

  1. Khởi tạo number = 5, count = 0.
  2. Kiểm tra điều kiện: number <= 100 (5 <= 100) là true.
  3. Thực thi: number = 5 * 2 = 10, count tăng lên 1. In ra "Lần lặp 1: number = 10".
  4. Kiểm tra điều kiện: number <= 100 (10 <= 100) là true.
  5. Thực thi: number = 10 * 2 = 20, count tăng lên 2. In ra "Lần lặp 2: number = 20".
  6. ... Lặp lại ...
  7. Khi number là 80, điều kiện (80 <= 100) là true. Thực thi: number = 80 * 2 = 160, count tăng lên 5. In ra "Lần lặp 5: number = 160".
  8. Kiểm tra điều kiện: number <= 100 (160 <= 100) là false. Vòng lặp kết thúc.
  9. In ra "Vòng lặp kết thúc. Giá trị cuối cùng của number: 160".

Đây là ví dụ điển hình cho while - chúng ta không biết trước cần bao nhiêu lần nhân đôi để number vượt quá 100, chỉ biết rằng nó sẽ lặp cho đến khi điều kiện đó xảy ra.

3. Vòng lặp do...while

Vòng lặp do...while rất giống với while, nhưng có một điểm khác biệt quan trọng: nó thực thi khối code ít nhất một lần trước khi kiểm tra điều kiện.

Cú pháp:

do {
  // Khối code này sẽ chạy ít nhất một lần
  // Sau đó nó sẽ lặp lại miễn là điều_kiện còn true
  // Đảm bảo có lệnh nào đó làm thay đổi điều kiện
} while (điều_kiện);

Giải thích:

  • Khối code trong do { ... } được thực thi đầu tiên.
  • Sau đó, điều_kiện trong while (...) được kiểm tra.
  • Nếu điều_kiệntrue, vòng lặp tiếp tục quay lại thực thi khối code trong do.
  • Nếu điều_kiệnfalse, vòng lặp kết thúc.

Ví dụ (Mô phỏng nhập liệu cho đến khi nhập đúng giá trị):

let userInput;

do {
  userInput = prompt("Nhập một số lớn hơn 10:");
  // prompt() trả về string, cần chuyển sang number nếu muốn so sánh số học
  userInput = Number(userInput);
} while (userInput <= 10 || isNaN(userInput));

console.log("Bạn đã nhập số hợp lệ: " + userInput);

Hãy phân tích đoạn code trên:

  1. Biến userInput được khai báo nhưng chưa có giá trị ban đầu.
  2. Khối do { ... } được thực thi lần đầu tiên mà không cần kiểm tra điều kiện nào. Cửa sổ prompt hiện ra yêu cầu người dùng nhập số.
  3. Sau khi người dùng nhập và nhấn OK, giá trị nhập được gán cho userInput, sau đó được chuyển sang kiểu Number.
  4. Kiểm tra điều kiện: userInput <= 10 || isNaN(userInput).
    • isNaN(userInput) kiểm tra xem giá trị nhập có phải là "Not a Number" không (ví dụ: người dùng nhập chữ).
    • Điều kiện này là true nếu số nhập nhỏ hơn hoặc bằng 10 HOẶC không phải là số.
  5. Nếu điều kiện là true (số không hợp lệ), vòng lặp tiếp tục, cửa sổ prompt hiện ra lại.
  6. Nếu điều kiện là false (số hợp lệ, tức là lớn hơn 10 và là số), vòng lặp kết thúc.
  7. In ra số hợp lệ đã nhập.

Vòng lặp do...while rất phù hợp khi bạn cần đảm bảo một hành động (như hiển thị menu, yêu cầu nhập dữ liệu) xảy ra ít nhất một lần.

4. Lệnh Điều khiển Vòng lặp (breakcontinue)

Đôi khi, bạn muốn kiểm soát chi tiết hơn luồng chạy bên trong vòng lặp. Hai lệnh phổ biến là breakcontinue.

  • break: Dừng vòng lặp ngay lập tức và thoát ra khỏi nó. Code tiếp tục thực thi từ lệnh ngay sau vòng lặp.

    Ví dụ (break):

    for (let i = 1; i <= 10; i++) {
      if (i === 5) {
        console.log("Tìm thấy số 5! Dừng vòng lặp.");
        break; // Thoát khỏi vòng lặp ngay lập tức
      }
      console.log("Kiểm tra số: " + i);
    }
    console.log("Đã thoát khỏi vòng lặp.");
    

    Giải thích: Vòng lặp chạy từ 1 đến 10. Khi i bằng 5, điều kiện if (i === 5) đúng. Dòng chữ được in ra, sau đó lệnh break được thực thi. Vòng lặp for dừng lại, và dòng chữ "Đã thoát khỏi vòng lặp." được in ra. Các số 6, 7, 8, 9, 10 không bao giờ được kiểm tra.

  • continue: Bỏ qua phần còn lại của lần lặp hiện tại và chuyển sang lần lặp tiếp theo.

    Ví dụ (continue):

    for (let i = 1; i <= 10; i++) {
      if (i % 2 === 0) { // Nếu số i là số chẵn
        console.log("Bỏ qua số chẵn: " + i);
        continue; // Bỏ qua các lệnh còn lại trong lần lặp này, chuyển sang i++
      }
      console.log("Xử lý số lẻ: " + i);
    }
    console.log("Hoàn thành kiểm tra các số.");
    

    Giải thích: Vòng lặp chạy từ 1 đến 10. Khi i là số chẵn (2, 4, 6, 8, 10), điều kiện if (i % 2 === 0) đúng. Dòng chữ "Bỏ qua số chẵn: ..." được in ra, sau đó lệnh continue được thực thi. Lệnh console.log("Xử lý số lẻ: " + i); bị bỏ qua cho lần lặp đó, và vòng lặp nhảy sang bước nhảy (i++) để bắt đầu lần lặp tiếp theo. Các dòng "Xử lý số lẻ: ..." chỉ được in ra khi i là số lẻ (1, 3, 5, 7, 9).

breakcontinue là những công cụ mạnh mẽ để tinh chỉnh luồng điều khiển trong vòng lặp của bạn.

Comments

There are no comments at the moment.