for...of

Bản dịch này chưa hoàn thành. Xin hãy giúp dịch bài viết này từ tiếng Anh

Cú pháp for...of để chạy vòng lặp trên String, Array, đối tượng tương tự Array (như arguments hoặc NodeList), TypedArray, Map, Set.

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 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 String

const iterable = 'boo';

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

Lặp qua TypedArray

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

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

Lặp qua một 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 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 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ư 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 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 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 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ả Array sẽ kết thừa thuộc tính arrCustom bởi vì chúng ta thêm nó vào bằng Object.prototypeArray.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 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ú
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of 'for...of statement' in that specification.
Standard Initial definition.
ECMAScript (ECMA-262)
The definition of 'for...of statement' in that specification.
Living Standard

Trình duyệt hổ trợ

Update compatibility data on GitHub
DesktopMobileServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidFirefox for AndroidOpera for AndroidSafari on iOSSamsung InternetNode.js
for...ofChrome Full support 38Edge Full support 12Firefox Full support 13
Notes
Full support 13
Notes
Notes Prior to Firefox 51, using the for...of loop construct with the const keyword threw a SyntaxError ("missing = in const declaration").
IE No support NoOpera Full support 25Safari Full support 7WebView Android Full support 38Chrome Android Full support 38Firefox Android Full support 14
Notes
Full support 14
Notes
Notes Prior to Firefox 51, using the for...of loop construct with the const keyword threw a SyntaxError ("missing = in const declaration").
Opera Android Full support 25Safari iOS Full support 7Samsung Internet Android Full support 3.0nodejs Full support 0.12
async iteratorsChrome Full support 63Edge Full support 12Firefox Full support 57IE No support NoOpera Full support 50Safari Full support 7WebView Android Full support 63Chrome Android Full support 63Firefox Android Full support 57Opera Android Full support 46Safari iOS Full support 7Samsung Internet Android Full support 8.0nodejs Full support 10.0.0
Closing iteratorsChrome Full support 51Edge Full support 14Firefox Full support 53IE No support NoOpera Full support 38Safari Full support 7WebView Android Full support 51Chrome Android Full support 51Firefox Android Full support 53Opera Android Full support 41Safari iOS Full support 7Samsung Internet Android Full support 5.0nodejs Full support 6.5.0

Legend

Full support  
Full support
No support  
No support
See implementation notes.
See implementation notes.

Xem thêm