--- title: Loops and iteration slug: Web/JavaScript/Guide/Loops_and_iteration translation_of: Web/JavaScript/Guide/Loops_and_iteration ---
Vòng lặp giúp thực hiện một hành động nhiều lần một cách nhanh chóng và đơn giản. Chương Hướng dẫn JavaScript này giới thiệu về các câu lệnh lặp trong JavaScript.
Hãy tưởng tượng vòng lặp giống như phiên bản vi tính của trò chơi mà bạn bảo một người đi X bước sang một hướng rồi đi Y bước sang một hướng khác; chẳng hạn, ý tưởng trò "Tiến 5 bước về phía Đông" có thể được biểu diễn dưới dạng vòng lặp như sau:
var step; for (let step = 0; step < 5; step++) { // Chạy 5 lần, với giá trị chạy từ 0 đến 4. console.log('Walking east one step'); }
Có nhiều kiểu vòng lặp khác nhau, nhưng tất cả đều thực hiện cùng một việc: làm lại một hành động trong số lần nhất định (số lần đó có thể là 0). Mỗi vòng lặp có các cơ chế khác nhau, tương ứng với đó là sự khác nhau giữa cách xác định điểm bắt đầu và kết thúc của vòng lặp. Tuỳ theo trường hợp xác định mà lựa kiểu vòng lặp cho phù hợp..
Các lệnh lặp trong JavaScript là:
for
Vòng lặp {{jsxref("statements/for","for")}} thực hiện liên tục cho tới khi điều kiện ban đầu trả về false. Vòng for
trong JavaScript tương tự như vòng for
trong Java hoặc C. Lệnh for
có dạng như sau:
for ([biểu_thức_khởi_tạo]; [điều_kiện]; [biểu_thức_tăng_tiến]) lệnh
Vòng lặp for
thực thi như sau:
biểu_thức_khởi_tạo
), nếu có, được thực thi. Biểu thức này thường khởi tạo một hoặc nhiều biến đếm cho vòng lặp, nhưng cú pháp của nó vẫn có thể tạo ra biểu thức có độ phức tạp. Biểu thức này còn có thể khai báo biến.điều_kiện
) được tính toán. Nếu giá trị của điều_kiện
trả về true, các lệnh trong vòng lặp được thực thi. Nếu giá trị của điều_kiện
trả về false, vòng lặp for
bị dừng lại. Nếu biểu thức điều_kiện
bị khuyết (bỏ qua không đặt), điều kiện sẽ được gán giả định là true.lệnh
sẽ được thực thi. Để thực thi nhiều lệnh, dùng khối lệnh ({ ... }
) để gom nhóm các lệnh này.biểu_thức_tăng_tiến
) được thực thi.Hàm dưới đây chứa lệnh for
đếm số option được chọn trong danh sách cuộn (phần tử {{HTMLElement("select")}} cho phép chọn nhiều). Lệnh for
khai báo biến i
và khởi tạo cho nó là 0. Điều kiện kiểm tra i
có nhỏ hơn số option mà phần tử <select>
sở hữu hay không, nếu thoả mãn điều kiện, chương trình sẽ chạy vào lệnh if
, và tăng i
thêm một.
<form name="selectForm"> <p> <label for="musicTypes">Choose some music types, then click the button below:</label> <select id="musicTypes" name="musicTypes" multiple="multiple"> <option selected="selected">R&B</option> <option>Jazz</option> <option>Blues</option> <option>New Age</option> <option>Classical</option> <option>Opera</option> </select> </p> <p><input id="btn" type="button" value="How many are selected?" /></p> </form> <script> function howMany(selectObject) { var numberSelected = 0; for (var i = 0; i < selectObject.options.length; i++) { if (selectObject.options[i].selected) { numberSelected++; } } return numberSelected; } var btn = document.getElementById('btn'); btn.addEventListener('click', function() { alert('Number of options selected: ' + howMany(document.selectForm.musicTypes)); }); </script>
do...while
Lệnh {{jsxref("statements/do...while", "do...while")}} thực hiện liên tục cho tới khi điều kiện xác định trả về false. Lệnh do...while
có dạng như sau:
do lệnh while (điều_kiện);
lệnh
luôn được thực thi một lần trước khi kiểm tra điều kiện (và rồi cứ thế cho tới khi điều kiện trả về false). Để thực thi nhiều lệnh, dùng khối lệnh ({ ... }
) để gom nhóm các câu lệnh. Nếu điều_kiện
trả về true, lệnh lại được thực thi một lần nữa. Sau mỗi lần thực thi, chương trình kiểm tra lại điều kiện. Khi điều kiện trả về false, chương trình dừng thực thi vòng lặp và truyền điều khiển xuống lệnh liền sau vòng do...while
.
Trong ví dụ sau, lặp do
lặp ít nhất một lần và tái duyệt cho tới khi i
không nhỏ hơn 5.
var i = 0; do { i += 1; console.log(i); } while (i < 5);
while
Lệnh {{jsxref("statements/while","while")}} thực thi các lệnh bên trong nó ngay khi điều kiện xác định trả về true. Lệnh while
có dạng như sau:
while (điều_kiện) lệnh
Nếu điều kiện trả về false, chương trình sẽ ngừng thực thi lệnh
bên trong vòng lặp và truyền điều khiển xuống lệnh liền sau vòng lặp.
Chương trình kiểm tra điều kiện trước khi thực thi lệnh
bên trong. Nếu điều kiện trả về true, lệnh
sẽ được thực thi và kiểm tra lại điều kiện. Nếu điều kiện trả về false, ngừng thực thi và truyền điều khiển xuống lệnh liền sau vòng lặp while
.
Để thực thi nhiều lệnh, dùng khối lệnh ({ ... }) để gom nhóm các câu lệnh.
Vòng while
lặp lại cho tới khi n
nhỏ hơn 3:
var n = 0; var x = 0; while (n < 3) { n++; x += n; }
Ứng với mỗi lần lặp, tăng n
thêm một và cộng giá trị đó vào x
. Bởi vậy, x
và n
có giá trị như sau:
n
= 1 và x
= 1n
= 2 và x
= 3n
= 3 và x
= 6Sau khi hoàn thành lần lặp thứ ba, điều kiện n < 3
không còn trả về true nữa nên vòng lặp bị kết thúc.
Hãy tránh lặp vô hạn. Hãy đảm bảo rằng điều kiện của vòng lặp sẽ dần trả về false; bằng không, vòng lặp sẽ không bao giờ kết thúc. Lệnh trong vòng lặp while
dưới đây được thực thi mãi mãi vì điều kiện không bao giờ trả về false:
while (true) { console.log('Hello, world!'); }
{{jsxref("statements/label","label")}} tạo ra một lệnh đi kèm với một định danh, thông qua định danh giúp bạn tham chiếu tới nó từ những nơi khác trong chương trình của bạn. Chẳng hạn, bạn có thể dùng nhãn để định danh một vòng lặp, rồi dùng lệnh break
hoặc continue
để chương trình xác định có nên dừng hay tiếp tục thực thi vòng lặp hay không.
Cú pháp của lệnh gán nhãn có dạng như sau:
nhãn : lệnh
Giá trị của nhãn
có thể là định danh JavaScript bất kỳ nhưng không phải từ dành riêng (tên biến, tên hàm hoặc nhãn khác). lệnh
được gán với nhãn có thể là bất kỳ lệnh nào.
Trong ví dụ này, nhãn markLoop
giúp định danh cho một vòng lặp while
.
markLoop: while (theMark == true) { doSomething(); }
break
Dùng lệnh {{jsxref("statements/break","break")}} để kết thúc vòng lặp, kết thúc switch
, hoặc liên hợp với một lệnh được gán nhãn.
break
không kèm với nhãn, chương trình kết thúc ngay tức thì vòng while
, do-while
, for
, hoặc switch
trong cùng bọc lệnh break
và truyền điều khiển xuống lệnh liền sau.break
kèm với nhãn, nó sẽ chấm dứt việc thực thi lệnh được gắn nhãn đó.Cú pháp lệnh break
có dạng như sau:
break; break [nhãn];
Kiểu cú pháp đầu tiên kết thúc vòng lặp trong cục bao bọc hoặc switch
; kiểu thứ hai kết thúc lệnh gắn với nhãn.
Trong ví dụ sau, lệnh lặp sẽ lặp qua từng phần tử của mảng (thông qua chỉ mục của từng phần tử) cho tới khi gặp phần tử có giá trị bằng theValue
:
for (var i = 0; i < a.length; i++) { if (a[i] == theValue) { break; } }
var x = 0; var z = 0; labelCancelLoops: while (true) { console.log('Outer loops: ' + x); x += 1; z = 1; while (true) { console.log('Inner loops: ' + z); z += 1; if (z === 10 && x === 10) { break labelCancelLoops; } else if (z === 10) { break; } } }
continue
Lệnh {{jsxref("statements/continue","continue")}} có thể dùng để tái duyệt các vòng while
, do-while
, for
, hoặc label
.
continue
không kèm theo label, chương trình ngừng thực thi lần lặp hiện tại của vòng while
, do-while
, hoặc for
gần nhất bọc lệnh continue
và tiếp tục thực thi lần lặp tiếp theo. Trái với lệnh break
, continue
không dừng vòng lặp hoàn toàn. Trong vòng lặp while
, chương trình nhảy về đoạn xét điều kiện. Trong vọng lặp for
, chương trình nhảy tới biểu_thức_tăng_tiến
.continue
có kèm theo label, lệnh continue
sẽ áp dụng cho vòng lặp được gán nhãn đó.Cú pháp của lệnh continue
có dạng như sau:
continue [label];
Trong ví dụ sau, vòng while
với lệnh continue
thực thi khi giá trị của i
bằng 3. Thế nên, n
sẽ có giá trị là 1, 3, 7 và 12.
var i = 0; var n = 0; while (i < 5) { i++; if (i == 3) { continue; } n += i; console.log(n); } //1,3,7,12 var i = 0; var n = 0; while (i < 5) { i++; if (i == 3) { // continue; } n += i; console.log(n); } // 1,3,6,10,15
Lệnh nhãn checkiandj
chứa nhãn checkj
. Nếu chương trình chạy tới continue
, chương trình sẽ ngừng thực hiện lần lặp hiện tại của checkj
và bắt đầu thực hiện lần lặp kế tiếp. Mỗi khi chạy tới continue
, checkj
tái duyệt cho tới khi biểu thức điều kiện của nó trả về false
. Khi false
được trả về, phần còn lại của lệnh checkiandj
được hoàn thành, và checkiandj
tái duyệt cho tới khi điều kiện của nó trả về false
. Khi false
được trả về, chương trình tiếp tục thực thi lệnh liền sau checkiandj
.
Nếu continue
gắn với nhãn checkiandj
, chương trình sẽ tiếp tục ở đầu lệnh checkiandj
.
var i = 0; var j = 10; checkiandj: while (i < 4) { console.log(i); i += 1; checkj: while (j > 4) { console.log(j); j -= 1; if ((j % 2) == 0) { continue checkj; } console.log(j + ' is odd.'); } console.log('i = ' + i); console.log('j = ' + j); }
for...in
Lệnh {{jsxref("statements/for...in","for...in")}} lặp một biến (variable) đã được xác định trước, qua mọi thuộc tính có thể đếm được (enumerable properties) của đối tượng (object). Với từng phần tử riêng biệt, JavaScript thực thi các câu lệnh mà bạn định sẵn. Lệnh for...in
có dạng như sau:
for (variable in object) statement
Hàm sau nhận vào tham số là một object và tên của object đó. Sau đó nó lặp qua mọi thuộc tính của object, với mỗi lần lặp nó trả về một chuỗi ký tự liệt kê các tên thuộc tính và giá trị của chúng.
function dump_props(obj, obj_name) { var result = ''; for (var i in obj) { result += obj_name + '.' + i + ' = ' + obj[i] + '<br>'; } result += '<hr>'; return result; }
Chẳng hạn với object car
có thuộc tính là make
và model
, result
sẽ là:
car.make = Ford car.model = Mustang
Mặc dù có thể dùng cách này để lặp qua từng phần tử của mảng {{jsxref("Array")}}, lệnh for...in
sẽ trả về tên của thuộc tính mà người dùng tự định nghĩa kèm theo chỉ mục của mảng.
Bởi vậy, tốt hơn hết hãy sử dụng cách truyền thống là dùng vòng lặp {{jsxref("statements/for","for")}} với chỉ mục dạng số để lặp qua từng phần tử của mảng, bởi lệnh for...in
còn lặp qua cả thuộc tính mà người dùng tự định nghĩa (chẳng hạn như khi thêm một thuộc tính vào mảng, sẽ có ví dụ ở phía dưới).
for...of
statementLệnh {{jsxref("statements/for...of","for...of")}} tạo ra một vòng lặp, áp dụng với các đối tượng khả duyệt (iterable object) (bao gồm {{jsxref("Array")}}, {{jsxref("Map")}}, {{jsxref("Set")}}, {{jsxref("functions/arguments","arguments")}} object, v.v...), và gọi lên một hook lặp tùy chỉnh (custom iteration hook) với các câu lệnh sẽ được thực thi cho giá trị của từng thuộc tính.
for (variable of object) statement
Ví dụ sau chỉ ra sự khác biệt giữa hai vòng lặp: for...of
và {{jsxref("statements/for...in","for...in")}}. Trong khi for...in
lặp qua tên thuộc tính, for...of
lặp qua giá trị thuộc tính:
var arr = [3, 5, 7]; arr.foo = 'hello'; for (var i in arr) { console.log(i); // logs "0", "1", "2", "foo" } for (var i of arr) { console.log(i); // logs 3, 5, 7 }
{{PreviousNext("Web/JavaScript/Guide/Control_flow_and_error_handling", "Web/JavaScript/Guide/Functions")}}