--- title: for...of slug: Web/JavaScript/Reference/Statements/for...of tags: - ECMAScript 2015 - JavaScript - Reference - Statement translation_of: Web/JavaScript/Reference/Statements/for...of ---
Cú pháp for...of
để chạy vòng lặp trên {{jsxref("String")}}, {{jsxref("Array")}}, đối tượng tương tự Array
(như {{jsxref("Functions/arguments", "arguments")}} hoặc {{domxref("NodeList")}}), {{jsxref("TypedArray")}}, {{jsxref("Map")}}, {{jsxref("Set")}}.
Ví dụ được lưu trên GitHub repository. Nếu muốn đóng góp, bạn có thể clone https://github.com/mdn/interactive-examples và gởi lên pull request.
for (tên-biến of đối-tượng-chạy-vòng-lặp) { ...câu lệnh... }
tên biến
đối tượng để chạy vòng lặp
let iterable = [10, 20, 30]; for (let value of iterable ) { value += 1; console.log(value); } // 11 // 21 // 31
Có thể khai báo bằng const
thay cho let
, nếu không có thay đổi biến bên trong vòng lặp.
let iterable= [10, 20, 30]; for (const value of iterable) { console.log(value); } // 10 // 20 // 30
const iterable = 'boo'; for (const value of iterable) { console.log(value); } // "b" // "o" // "o"
const iterable = new Uint8Array([0x00, 0xff]); for (const value of iterable) { console.log(value); } // 0 // 255
const iterable = new Map([['a', 1], ['b', 2], ['c', 3]]); for (const entry of iterable) { console.log(entry); } // ['a', 1] // ['b', 2] // ['c', 3] for (const [key, value] of iterable) { console.log(value); } // 1 // 2 // 3
const iterable = new Set([1, 1, 2, 2, 3, 3]); for (const value of iterable) { console.log(value); } // 1 // 2 // 3
arguments
Lặp qua đối tượng {{jsxref("Functions/arguments", "arguments")}} để có tất cả giá trị được truyền vào trong hàm:
(function() { for (const argument of arguments) { console.log(argument); } })(1, 2, 3); // 1 // 2 // 3
Lặp qua một tập DOM như {{domxref("NodeList")}}: ví dụ bên dưới, thêm class read
cho các đoạn văn bản nào là con trực tiếp của article:
// Lưu ý: Chỉ hoạt động động trên các platforms có // hiện thực NodeList.prototype[Symbol.iterator] const articleParagraphs = document.querySelectorAll('article > p'); for (const paragraph of articleParagraphs) { paragraph.classList.add('read'); }
Trong vòng lặp for...of
, có thể ngừng lặp giữa chừng bằng break
, continue
, throw
hoặc return
. Trong các trường hợp này, vòng lặp sẽ được ngưng lại.
function* foo(){ yield 1; yield 2; yield 3; }; for (const o of foo()) { console.log(o); break; // đóng vòng lặp, tiếp tục thực thi bên ngoài vòng lặp } console.log('Xong')
Bạn cũng có thể lặp qua hàm generators, ví dụ:
function* fibonacci() { // một hàm generator let [prev, curr] = [0, 1]; while (true) { [prev, curr] = [curr, prev + curr]; yield curr; } } for (const n of fibonacci()) { console.log(n); // truncate the sequence at 1000 if (n >= 1000) { break; } }
Không nên re-used Generator, ngay cả khi vòng lặp for...of
bị kết thúc sớm bằng {{jsxref("Statements/break", "break")}}. Khi thoát khỏi vòng lặp, generator sẽ kết thúc và cố lặp lại lần nữa sẽ không cho thêm bất kỳ kết quả yield nào khác.
const gen = (function *(){ yield 1; yield 2; yield 3; })(); for (const o of gen) { console.log(o); break; // Closes iterator } // Không dùng lại generator, đoạn code như thế này không hợp lý! for (const o of gen) { console.log(o); // Không bao giờ được gọi }
Bạn cũng có thể loop qua các đối tượng tự định nghĩa, nếu có hiện thực iterable:
const iterable = { [Symbol.iterator]() { return { i: 0, next() { if (this.i < 3) { return { value: this.i++, done: false }; } return { value: undefined, done: true }; } }; } }; for (const value of iterable) { console.log(value); } // 0 // 1 // 2
for...of
và for...in
Cú pháp {{jsxref("Statements/for...in", "for...in")}} lặp qua các đối tượng được đếm, theo một thứ tự tùy ý.
Cú pháp for...of
lặp qua đối tượng dữ liệu có thể lặp.
Ví dụ sau để thấy sự khác nhau giữa for...of
và for...in
khi sử dụng với {{jsxref("Array")}}.
Object.prototype.objCustom = function() {}; Array.prototype.arrCustom = function() {}; const iterable = [3, 5, 7]; iterable.foo = 'hello'; for (const i in iterable) { console.log(i); // logs 0, 1, 2, "foo", "arrCustom", "objCustom" } for (const i in iterable) { if (iterable.hasOwnProperty(i)) { console.log(i); // logs 0, 1, 2, "foo" } } for (const i of iterable) { console.log(i); // logs 3, 5, 7 }
Giải thích ví dụ trên
Object.prototype.objCustom = function() {}; Array.prototype.arrCustom = function() {}; const iterable = [3, 5, 7]; iterable.foo = 'hello';
Tất cả object sẽ kế thừa thuộc tính objCustom
và tất cả {{jsxref("Array")}} sẽ kết thừa thuộc tính arrCustom
bởi vì chúng ta thêm nó vào bằng {{jsxref("Object.prototype")}} và {{jsxref("Array.prototype")}}. iterable
kế thừa cả objCustom
và arrCustom
.
for (const i in iterable) { console.log(i); // logs 0, 1, 2, "foo", "arrCustom", "objCustom" }
Vòng vòng lặp này chỉ log thuộc tính được đếm của iterable
, theo thứ tự được đưa vào. Nó không log các element của array 3
, 5
, 7
hoặc hello
bởi vì nó là không thuộc tính được đếm. Nó log giá trị index cũng như arrCustom
và objCustom
.
for (let i in iterable) { if (iterable.hasOwnProperty(i)) { console.log(i); // logs 0, 1, 2, "foo" } }
Vòng loop tương tự như ở trên, nhưng sử dụng {{jsxref("Object.prototype.hasOwnProperty()", "hasOwnProperty()")}} để kiểm tra, nếu tìm thấy một property của chính nó chứ không phải kế thừa và log kết quả ra. Các Property 0
, 1
, 2
và foo
được log bởi vì nó không phải được kết thừa.
for (const i of iterable) { console.log(i); // logs 3, 5, 7 }
Vòng lặp và log ra giá trị bên trong đối tượng iterable
như một iterable object được khai báo để lặp, chính là các element bên trong mảng 3
, 5
, 7
và không bao gồm các property của object.
Đặc điểm | Status | Ghi chú |
---|---|---|
{{SpecName('ES2015', '#sec-for-in-and-for-of-statements', 'for...of statement')}} | {{Spec2('ES2015')}} | Initial definition. |
{{SpecName('ESDraft', '#sec-for-in-and-for-of-statements', 'for...of statement')}} | {{Spec2('ESDraft')}} |
{{Compat("javascript.statements.for_of")}}