--- title: for...of slug: Web/JavaScript/Reference/Statements/for...of tags: - ECMAScript 2015 - JavaScript - Reference - Statement translation_of: Web/JavaScript/Reference/Statements/for...of ---
{{jsSidebar("Statements")}}

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")}}.

{{EmbedInteractiveExample("pages/js/statement-forof.html")}}

Cú pháp

for (tên-biến of đối-tượng-chạy-vòng-lặp) {
  ...câu lệnh...
}
tên biến

Trên mỗi lần lặp, một giá trị của một thuộc tính khác nhau được gán cho biến. biến có thể được khai báo với const, let hoặc var.
đối tượng để chạy vòng lặp
Đối tượng có các thuộc tính có thể được lặp lại (iterable).

Ví dụ

Lặp qua một {{jsxref("Array")}}

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

Lặp qua một {{jsxref("String")}}

const iterable = 'boo';

for (const value of iterable) {
  console.log(value);
}
// "b"
// "o"
// "o"

Lặp qua {{jsxref("TypedArray")}}

const iterable = new Uint8Array([0x00, 0xff]);

for (const value of iterable) {
  console.log(value);
}
// 0
// 255

Lặp qua một {{jsxref("Map")}}

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

Loop qua một {{jsxref("Set")}}

const iterable = new Set([1, 1, 2, 2, 3, 3]);

for (const value of iterable) {
  console.log(value);
}
// 1
// 2
// 3

Lặp qua một đối tượng 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

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');
}

Đóng vòng lặp

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')

Lặp qua generator

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 tái sử dụng generator

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
}

Lặp qua các đối tượng khác

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

Sự khác biệt giữa for...offor...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ả objCustomarrCustom.

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ư arrCustomobjCustom.

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, 2foo đượ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

Đặ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')}}

Trình duyệt hổ trợ

{{Compat("javascript.statements.for_of")}}

Xem thêm