Chúng ta thường cần lặp lại hành động nào đó.

Ví dụ: xuất hàng hóa từ danh sách này sang danh sách khác hoặc chỉ chạy cùng một code với số từ 1 đến 10.

Vòng lặp là một cách để lặp lại cùng một code nhiều lần.

1. Vòng lặp while

Các vòng lặp while có cú pháp sau:

while (condition) {
  // code
  // so-called "loop body"
}

Trong khi condition là true, phần thân codetrong vòng lặp được thực thi.

Chẳng hạn, vòng lặp bên dưới xuất ra i cho tới i < 3:

let i = 0;
while (i < 3) { // shows 0, then 1, then 2
  alert( i );
  i++;
}

Cứ Một lần thực thi thân vòng lặp được gọi là phép lặp. Vòng lặp trong ví dụ trên tạo ra ba lần lặp.

Nếu i++bị thiếu trong ví dụ trên, vòng lặp sẽ lặp lại (về lý thuyết) mãi mãi. Trong thực tế, trình duyệt cung cấp các cách để ngăn chặn các vòng lặp như vậy trong JavaScript ở phía máy chủ, chúng ta có thể giết tiến trình này.

Bất kỳ biểu thức hoặc biến nào cũng có thể là điều kiện vòng lặp, không chỉ là so sánh: điều kiện được ước tính và chuyển đổi thành boolean bởi while.

-->

Chẳng hạn, một cách viết ngắn hơn while (i != 0)while (i):

/*
Cafedev.vn - Kênh thông tin IT hàng đầu Việt Nam
@author cafedevn
Contact: cafedevn@gmail.com
Fanpage: https://www.facebook.com/cafedevn
Instagram: https://instagram.com/cafedevn
Twitter: https://twitter.com/CafedeVn
Linkedin: https://www.linkedin.com/in/cafe-dev-407054199/
*/

let i = 3;
while (i) { // when i becomes 0, the condition becomes falsy, and the loop stops
  alert( i );
  i--;
}

Nếu thân vòng lặp có một câu lệnh đơn, chúng ta có thể bỏ qua dấu ngoặc nhọn {…}:

let i = 3;
while (i) alert(i--);

2. Vòng lặp do … while

Kiểm tra điều kiện có thể được di chuyển vào bên trong thân vòng lặp bằng do..whilecú pháp:

do {
  // loop body
} while (condition);

Vòng lặp trước tiên sẽ thực thi phần thân, sau đó kiểm tra điều kiện và trong khi điều kiện là true, thì thực hiện lặp 1 lần. Cứ như vậy cho tới khi điều kiện là false

Ví dụ:

let i = 0;
do {
  alert( i );
  i++;
} while (i < 3);

Dạng cú pháp này chỉ nên được sử dụng khi bạn muốn phần thân của vòng lặp thực thi ít nhất một lần bất kể điều kiện là sai. Thông thường, các hình thức khác được ưa thích : while(…) {…}.

3. Các vòng lặp với for

Các vòng lặp for phức tạp hơn, nhưng nó cũng là vòng lặp thường được sử dụng nhất.

Nó trông như thế này:

for (begin; condition; step) {
  // ... loop body ...
}

Hãy tìm hiểu ý nghĩa của những phần này bằng ví dụ. Vòng lặp bên dưới chạy alert(i)cho itừ 0lên đến (nhưng không bao gồm) 3:

for (let i = 0; i < 3; i++) { // shows 0, then 1, then 2
  alert(i);
}

Hãy xem xét từng vòng for của câu lệnh:

Vòng
bắt đầui = 0Thực hiện một lần khi vào vòng lặp.
tình trạngi < 3Kiểm tra trước mỗi lần lặp lặp. Nếu sai, vòng lặp dừng lại.
thân alert(i) Chạy đi chạy lại trong khi điều kiện là true.
bướci++Thực hiện sau mỗi lần lặp phần thân.

Thuật toán vòng lặp chung hoạt động như thế này:

Run begin
→ (if condition → run body and run step)
→ (if condition → run body and run step)
→ (if condition → run body and run step)
→ ...

Đó là, beginthực thi một lần, và sau đó lặp lại -> sau mỗi lần kiểm tra condition đúng sẽ thưc thi phần bodystep.

Nếu bạn chưa quen với các vòng lặp, mô tả và tái tạo cách nó chạy từng bước trên một tờ giấy.

Đây chính xác là những gì xảy ra trong trường hợp của chúng ta:

// for (let i = 0; i < 3; i++) alert(i)

// run begin
let i = 0
// if condition → run body and run step
if (i < 3) { alert(i); i++ }
// if condition → run body and run step
if (i < 3) { alert(i); i++ }
// if condition → run body and run step
if (i < 3) { alert(i); i++ }
// ...finish, because now i == 3

3.1 Khai báo biến nội tuyến

Ở đây, biến số đối lập iđược khai báo ngay trong vòng lặp. Điều này được gọi là một khai báo biến nội tuyến. Các biến như vậy chỉ được nhìn thấy bên trong vòng lặp.

for (let i = 0; i < 3; i++) {
  alert(i); // 0, 1, 2
}
alert(i); // error, no such variable

Thay vì khai báo một biến, chúng ta có thể sử dụng một biến hiện có:

let i = 0;

for (i = 0; i < 3; i++) { // use an existing variable
  alert(i); // 0, 1, 2
}

alert(i); // 3, visible, because declared outside of the loop

3.2 Bỏ qua các bộ phận

Bất kỳ phần nào của forcó thể được bỏ qua.

Ví dụ: chúng ta có thể bỏ qua beginnếu chúng ta không cần làm gì khi bắt đầu vòng lặp.

Giống như ở đây:

let i = 0; // we have i already declared and assigned

for (; i < 3; i++) { // no need for "begin"
  alert( i ); // 0, 1, 2
}

Chúng ta cũng có thể loại bỏ stepmột phần:

let i = 0;

for (; i < 3;) {
  alert( i++ );
}

Điều này làm cho vòng lặp giống hệt while (i < 3).

Chúng ta thực sự có thể loại bỏ mọi thứ, tạo ra một vòng lặp vô hạn:

for (;;) {
  // repeats without limits
}

Xin lưu ý rằng hai fordấu chấm phẩy ;phải có mặt. Nếu không, sẽ có một lỗi cú pháp.

4. Break vòng lặp

Thông thường, một vòng lặp thoát khi tình trạng của nó trở nên sai.

Nhưng chúng ta có thể buộc thoát ra bất cứ lúc nào bằng cách sử dụng breakchỉ thị đặc biệt .

Ví dụ: vòng lặp bên dưới yêu cầu người dùng cung cấp một loạt số, break khi không nhập số:

/*
Cafedev.vn - Kênh thông tin IT hàng đầu Việt Nam
@author cafedevn
Contact: cafedevn@gmail.com
Fanpage: https://www.facebook.com/cafedevn
Instagram: https://instagram.com/cafedevn
Twitter: https://twitter.com/CafedeVn
Linkedin: https://www.linkedin.com/in/cafe-dev-407054199/
*/

let sum = 0;

while (true) {

  let value = +prompt("Enter a number", '');

  if (!value) break; // (*)

  sum += value;

}
alert( 'Sum: ' + sum );

Lệnh breakđược kích hoạt tại dòng (*)nếu người dùng nhập vào một dòng trống hoặc hủy bỏ đầu vào. Nó dừng vòng lặp ngay lập tức, chuyển điều khiển đến dòng đầu tiên sau vòng lặp. Cụ thể làalert.

Vòng lặp vô hạn của tổ hợp + breakkhi cần thiết, rất phù hợp cho các tình huống khi phải kiểm tra điều kiện của vòng lặp không phải ở đầu hoặc cuối vòng lặp, mà ở giữa hoặc thậm chí ở một số vị trí trên cơ thể.

5. Tiếp tục đến lần lặp tiếp theo

Lệnh continuenày là một phiên bản nhẹ hơn của break. Nó không dừng toàn bộ vòng lặp. Thay vào đó, nó dừng việc lặp lại hiện tại và buộc vòng lặp bắt đầu một vòng lặp mới (nếu điều kiện cho phép).

Chúng ta có thể sử dụng nó nếu chúng ta đã hoàn thành với lần lặp hiện tại và muốn chuyển sang lần lặp tiếp theo.

Vòng lặp bên dưới chỉ sử dụng continueđể xuất các giá trị lẻ:

for (let i = 0; i < 10; i++) {

  // if true, skip the remaining part of the body
  if (i % 2 == 0) continue;

  alert(i); // 1, then 3, 5, 7, 9
}

Đối với các giá trị chẵn của i, lệnh continuedừng thực thi phần thân và chuyển điều khiển sang lần lặp tiếp theo của for(với số tiếp theo). Vì vậy, alertchỉ được gọi cho các giá trị lẻ.

Một vòng lặp hiển thị các giá trị kỳ lạ có thể trông như thế này:

for (let i = 0; i < 10; i++) {

  if (i % 2) {
    alert( i );
  }

}

Từ quan điểm kỹ thuật, điều này giống hệt với ví dụ trên. Chắc chắn, chúng ta chỉ có thể bọc code trong một khốiif thay vì sử dụng continue.

Nhưng như một hiệu ứng phụ, điều này tạo ra thêm một cấp độ lồng nhau (gọi alert bên trong các dấu ngoặc nhọn). Nếu code bên trong ifdài hơn một vài dòng, điều đó có thể làm giảm khả năng đọc code.

Không break/continueở bên phải của ‘?’

Xin lưu ý rằng các cấu trúc cú pháp không phải là biểu thức có thể được sử dụng với toán tử ternary ?. Cụ thể, các chỉ thị như break/continuekhông được phép ở đó.

Ví dụ: nếu chúng tôi lấy code này:

if (i > 5) {
  alert(i);
} else {
  continue;
}

Viết và viết lại bằng dấu chấm hỏi:

(i > 5) ? alert(i) : continue; // continue isn't allowed here

Không thể ngừng hoạt động: có lỗi cú pháp.

Đây chỉ là một lý do khác để không sử dụng toán tử dấu hỏi ?thay vì if.

6. Nhãn để break / continue

Đôi khi chúng ta cần thoát ra khỏi nhiều vòng lặp lồng nhau cùng một lúc.

Ví dụ: trong đoạn code bên dưới, chúng ta lặp lại ijnhắc nhở tọa độ (i, j)từ (0,0)đến (2,2):

for (let i = 0; i < 3; i++) {

  for (let j = 0; j < 3; j++) {

    let input = prompt(`Value at coords (${i},${j})`, '');

    // what if we want to exit from here to Done (below)?
  }
}

alert('Done!');

Chúng ta cần một cách để dừng quá trình nếu người dùng hủy bỏ đầu vào.

Bình thường breaksau inputsẽ chỉ phá vỡ vòng lặp bên trong, Nhưng không đủ.

Một nhãn là một định danh với một dấu hai chấm trước một vòng lặp:

labelName: for (...) {
  ...
}

Câu lệnhbreak <labelName> trong vòng lặp bên dưới sẽ thoát ra khỏi nhãn:

outer: for (let i = 0; i < 3; i++) {

  for (let j = 0; j < 3; j++) {

    let input = prompt(`Value at coords (${i},${j})`, '');

    // if an empty string or canceled, then break out of both loops
    if (!input) break outer; // (*)

    // do something with the value...
  }
}
alert('Done!');

Trong đoạn code trên, vớibreak outerta nhìn lên trên sẽ thấy nhãn có tên outervà nó sẽ thoát ra khỏi vòng lặp tại cái nhãn đó.

Vì vậy, luồng xử lý đi thẳng từ (*)đến alert('Done!').

Chúng ta cũng có thể di chuyển nhãn lên một dòng riêng biệt:

outer:
for (let i = 0; i < 3; i++) { ... }

Lệnh continuenày cũng có thể được sử dụng với nhãn. Trong trường hợp này, thực thi nhảy code đến lần lặp tiếp theo của vòng lặp được gắn nhãn. Nhãn không cho phép nhảy bất cứ nơi nào

Nhãn không cho phép chúng ta nhảy vào một vị trí tùy ý trong code.

Ví dụ, không thể làm điều này:

break label; // doesn't jumps to the label below

label: for (...)

Một lệnh gọi đến break/continuechỉ có thể từ bên trong một vòng lặp và nhãn phải ở đâu đó phía trên chỉ thị.

7. Tóm lược

Chúng ta bao gồm 3 loại vòng:

  • while – Điều kiện được kiểm tra trước mỗi lần lặp.
  • do..while – Điều kiện được kiểm tra sau mỗi lần lặp.
  • for (;;) – Điều kiện được kiểm tra trước mỗi lần lặp và một số điều kiện đi kèm.

Để tạo một vòng lặp vô hạn của người dùng, thông thường cấu trúc được sử dụng làwhile(true). Một vòng lặp như vậy, giống như bất kỳ vòng lặp nào khác, có thể được dừng lại bằng lệnh break.

Nếu chúng ta không muốn làm bất cứ điều gì trong lần lặp hiện tại và muốn chuyển tiếp đến lần tiếp theo, chúng ta có thể sử dụng lệnh continue.

break/continuevới nhãn hỗ trợ trước vòng lặp. Một nhãn thì duy nhất.break/continuedùng để thoát khỏi một vòng lặp lồng nhau để đi đến một vòng ngoài.

Đăng ký kênh youtube để ủng hộ Cafedev nha các bạn, Thanks you!