Menu

Vòng lặp for JavaScript: cú pháp, ví dụ, break, continue

Vòng lặp for cổ điển trong JavaScript hoạt động thế nào: phần đầu gồm ba phần, duyệt mảng, break và continue, vòng lặp lồng nhau và những lỗi thường gặp.

Trang này có trình soạn thảo chạy trực tiếp. Sửa, chạy và xem đầu ra ngay lập tức.

Vòng lặp for cổ điển

Khi bạn biết mình muốn lặp lại một việc bao nhiêu lần, vòng lặp (loop) for là công cụ phù hợp. Nó gói ba phần của một vòng lặp đếm (bắt đầu, dừng, bước nhảy) vào một dòng tiêu đề duy nhất.

Năm lần lặp, năm dòng đầu ra. Đọc phần tiêu đề:

  • let i = 0 chạy một lần, trước khi vòng lặp bắt đầu. Nó tạo biến đếm.
  • i < 5 được kiểm tra trước mỗi lần lặp. Nếu là true, thân vòng lặp chạy. Nếu là false, vòng lặp kết thúc.
  • i++ chạy sau mỗi lần lặp, ngay trước khi điều kiện được kiểm tra lại.

Ba phần được ngăn cách bằng dấu chấm phẩy, không phải dấu phẩy. Cả ba đều không bắt buộc, nhưng hiếm khi người ta bỏ chúng đi; khi đó bạn thường dùng while thay thế.

Các phần ăn khớp với nhau thế nào

Lần theo một vòng lặp bằng tay sẽ giúp bạn nhớ chắc thứ tự:

Từng bước một:

  1. let i = 1: biến đếm được tạo và gán bằng 1.
  2. Kiểm tra i <= 3: đúng, nên chạy thân vòng lặp. In ra 1.
  3. Chạy i++: i giờ là 2.
  4. Kiểm tra i <= 3: đúng. In ra 2.
  5. Chạy i++: i giờ là 3.
  6. Kiểm tra i <= 3: đúng. In ra 3.
  7. Chạy i++: i giờ là 4.
  8. Kiểm tra i <= 3: sai. Thoát.

Bước cập nhật chạy sau thân vòng lặp, không phải trước. Đó là chỗ người ta hay nhầm.

Duyệt mảng theo chỉ số

Việc phổ biến nhất của vòng lặp for là đi qua một mảng. Biến đếm kiêm luôn vai trò chỉ số:

Vài điều đáng để ý:

  • Mảng đánh chỉ số từ 0. Phần tử đầu tiên ở chỉ số 0, phần tử cuối ở length - 1.
  • Điều kiện là i < fruits.length, không phải i <= fruits.length. Dùng <= sẽ chạy quá cuối mảng một bước và in ra undefined.
  • i được khai báo bằng let, nên phạm vi của nó gói gọn trong vòng lặp. Bên ngoài vòng lặp, nó không tồn tại.

Nếu bạn chỉ cần giá trị mà không cần chỉ số, for...of ngắn gọn và rõ ràng hơn; chúng ta sẽ nói về nó trong một bài riêng.

break: dừng sớm

break thoát khỏi vòng lặp ngay lập tức. Rất hữu ích khi bạn đã tìm thấy thứ mình cần và không cần chạy tiếp:

Khi break chạy, chương trình nhảy qua dấu ngoặc nhọn đóng của vòng lặp. Bước cập nhật không chạy, điều kiện không được kiểm tra lại: vòng lặp đơn giản là kết thúc.

continue: bỏ qua lần lặp này

continue bỏ qua phần còn lại của lần lặp hiện tại và đi thẳng tới bước cập nhật. Vòng lặp vẫn tiếp tục chạy; nó chỉ không hoàn thành lượt hiện tại.

Các số chẵn gặp continue và bỏ qua console.log. Chỉ các số lẻ được in ra. continue tiện khi bạn muốn loại bỏ một số lần lặp mà không phải lồng phần còn lại của thân vòng lặp vào trong một if.

Bước nhảy khác +1

Bước cập nhật chỉ là một biểu thức. Nó không nhất thiết phải là i++. Đếm cách hai:

Đếm ngược:

Duyệt mảng từ cuối về đầu, đôi khi hữu ích khi bạn vừa duyệt vừa xóa phần tử:

Dù chọn cách nào, quy tắc vẫn vậy: điều kiện và bước cập nhật phải phối hợp với nhau để điều kiện cuối cùng trở thành false. Nếu không, vòng lặp sẽ chạy mãi. for (let i = 0; i < 10; i--) là một vòng lặp vô hạn: i đi sai hướng.

Vòng lặp for lồng nhau

Bạn có thể đặt một vòng lặp for bên trong một vòng lặp khác. Vòng lặp trong chạy hết cho mỗi lần lặp của vòng lặp ngoài.

Chín dòng đầu ra: ba lần lặp ngoài, mỗi lần có ba lần lặp trong. Hãy đặt cho mỗi biến đếm một cái tên có nghĩa (row/col, i/j) thay vì dùng lại cùng một biến.

Một điều cần lưu ý: break và continue chỉ ảnh hưởng tới vòng lặp trong cùng. Thoát khỏi vòng lặp trong không làm dừng vòng lặp ngoài. Nếu cần điều đó, hãy đặt một biến cờ và kiểm tra nó ở vòng lặp ngoài, hoặc tách phần lồng nhau ra thành một hàm và return từ hàm đó.

Những lỗi thường gặp

Vài thứ hay làm khó người mới:

Lỗi lệch một. i <= arr.length lặp quá một bước; i < arr.length - 1 dừng sớm một bước. Dạng chuẩn là i < arr.length.

Quên bước cập nhật. Nếu bạn bỏ sót i++ (hoặc thứ tương đương), biến đếm không bao giờ thay đổi và vòng lặp chạy mãi:

for (let i = 0; i < 10; ) {
    console.log(i); // never ends
}

Dùng var cho biến đếm. var có phạm vi hàm, nên biến đếm bị lọt ra ngoài vòng lặp và có thể gây bất ngờ trong closure. Hãy dùng let.

Sửa mảng trong lúc đang duyệt nó. Xóa phần tử làm các chỉ số bị dịch chuyển và bạn sẽ bỏ sót phần tử. Nếu cần xóa, hãy duyệt ngược, hoặc tạo một mảng mới bằng filter.

Khi nào nên dùng cách khác

Vòng lặp for cổ điển lúc nào cũng dùng được, nhưng JavaScript có những lựa chọn ngắn gọn hơn cho các trường hợp phổ biến:

  • Duyệt giá trị của mảng: for (const item of array) gọn hơn.
  • Biến đổi mảng: array.map(fn) trả về một mảng mới.
  • Lọc: array.filter(fn).
  • Tính tổng hoặc gộp: array.reduce(fn, start).
  • Chỉ làm một việc với từng phần tử: array.forEach(fn).

Hãy dùng vòng lặp for cổ điển khi bạn thật sự cần chỉ số, cần bỏ qua hoặc dừng giữa chừng, hoặc cần bước nhảy không chuẩn như đếm ngược hay đếm cách hai.

Tiếp theo: vòng lặp while

Vòng lặp for tỏa sáng khi bạn biết trước phạm vi. Khi không biết (khi bạn muốn tiếp tục cho đến khi một điều kiện nào đó thay đổi), while và do...while phù hợp hơn. Đó là nội dung của trang tiếp theo.

Câu hỏi thường gặp

Cú pháp của vòng lặp for trong JavaScript là gì?

Gồm ba phần cách nhau bằng dấu chấm phẩy trong cặp ngoặc tròn: for (init; condition; update) { ... }. Phần khởi tạo chạy một lần, điều kiện được kiểm tra trước mỗi lần lặp, và phần cập nhật chạy sau mỗi lần lặp. Một vòng lặp điển hình trông như for (let i = 0; i < 10; i++) { ... }.

Làm sao duyệt qua một mảng trong JavaScript?

Một vòng lặp for cổ điển với chỉ số là được: for (let i = 0; i < arr.length; i++) { console.log(arr[i]); }. Nếu không cần chỉ số, for...of gọn hơn: for (const item of arr) { ... }. Để biến đổi hay lọc mảng, các phương thức như map và filter thường là công cụ phù hợp.

break và continue hoạt động thế nào trong vòng lặp for?

break thoát khỏi vòng lặp ngay lập tức: chương trình nhảy tới đoạn code sau vòng lặp. continue bỏ qua phần còn lại của lần lặp hiện tại và đi thẳng tới bước cập nhật, rồi kiểm tra lại điều kiện. Cả hai chỉ ảnh hưởng tới vòng lặp trong cùng, trừ khi bạn dùng nhãn.

Tại sao vòng lặp for của tôi chạy mãi không dừng?

Thường là do bước cập nhật không bao giờ đưa điều kiện về false. for (let i = 0; i < 10; i--) đếm ngược mãi mãi vì i bắt đầu từ 0 và chỉ ngày càng âm hơn. Hãy kiểm tra lại điều kiện và bước cập nhật: chúng phải phối hợp với nhau để điều kiện cuối cùng trở thành sai.

Hình minh họa các ngôn ngữ lập trình của Coddy

Học lập trình cùng Coddy

Bắt đầu