1. Iterators trong JavaScript là gì?
Iterators là một bộ duyệt dùng để duyệt qua một mảng, một danh sách hoặc một collection mà qua mỗi lần duyệt sẽ ghi lại vị trí đã duyệt để từ đó có thể biết và lấy vị trí tiếp theo.
Trong Js thì iterators có chung cấp phương thức next() và phương thức này sẽ return về phần tử kết tiếp, đồng thời ghi nhận luôn phần tử đã lặp là phần tử next() . Phương thức next() sẽ return về một Object gồm hai thuộc tính là value và done .
Ví dụ:
<script> let arr = ['a', 'b', 'c']; var iterator = arr[Symbol.iterator](); document.write(iterator.next()); // a document.write(iterator.next()); // b document.write(iterator.next()); // c document.write(iterator.next()); // undefined </script>
Giá trị lần next() cuối cùng là một giá trị undefined và key done của nó sẽ là true . Và ta có
- Thuộc tính value có thể thuộc bất kỳ kiểu dữ liệu nào và đại diện cho giá trị hiện tại trong chuỗi.
- Thuộc tính done là một giá trị kiểu dữ liệu boolean cho biết quá trình lặp có hoàn thành hay không. Nếu quá trình lặp chưa hoàn thành, thuộc tính done được đặt giá trị false nếu không thuộc tính được đặt thành true .
2. Iterables trong JavaScript là gì?
Iterable trong Js là một khái niệm liên quan đến array . Đối tượng lặp (Iterable) là một sự khái quát của mảng. Đó là một khái niệm cho phép chúng ta làm cho bất kỳ đối tượng nào đó có thể sử dụng được trong một vòng lặp for..of .
Dĩ nhiên là mảng có thể lặp lại hay array chính là iterable . Tuy nhiên có nhiều đối tượng tích hợp khác cũng có thể lặp lại. Ví dụ như Set , Map , String , …
Ví dụ:
<script> const name = "Laptrinhtudau.com"; let text = "" for (const x of name) { text += x + "<br>"; } document.write(text); </script>
3. Duyệt qua các đối tượng Iterable trong JavaScript
Ta có thể sử dụng vòng lặp for…of để duyệt qua các đối tượng Iterable . Ta có thể thực hiện việc lặp thông qua phương thức Symbol.iterator() như sau:
const a = [100, 150, 160, 200, 250]; for (let i of a[Symbol.iterator]()) { console.log(i); }
Hoặc ta có thể chỉ cần lặp qua một mảng như sau:
const a = [150, 160, 170, 190, 250, 270]; for (let i of a) { console.log(i); }
Ở đây, đối tượng Iterator cho phép vòng lặp for…of lặp qua một mảng và trả về từng giá trị.
4. Symbol.iterator trong JavaScript
JavaScript có thể lặp lại là một đối tượng có Symbol.iterator . Hàm Symbol.iterator là một hàm trả về một hàm next() . Ta có thể lặp lại có thể lặp lại bằng mã: for (const x of iterable) { }
//Tạo một đối tượng myNumbers = {}; // Làm cho nó có thể lặp lại myNumbers[Symbol.iterator] = function() { let n = 0; done = false; return { next() { n += 10; if (n == 100) {done = true} return {value:n, done:done}; } }; }
Bây giờ ta có thể sử dụng for…of
<script> // Tạo một đối tượng myNumbers = {}; // Làm cho nó có thể lặp lại myNumbers[Symbol.iterator] = function() { let n = 0; done = false; return { next() { n += 10; if (n == 100) {done = true} return {value:n, done:done}; } }; } let text = "" for (const num of myNumbers) { text += num +"<br>" } document.write(text); </script>
Phương thức Symbol.iterator được gọi tự động bởi for..of . Nhưng chúng ta cũng có thể làm điều đó một cách “thủ công”:
<script> myNumbers = {}; myNumbers[Symbol.iterator] = function() { let n = 0; done = false; return { next() { n += 10; if (n == 100) {done = true} return {value:n, done:done}; } }; } let iterator = myNumbers[Symbol.iterator](); let text = "" while (true) { const result = iterator.next(); if (result.done) break; text += result.value +"<br>"; } document.write(text); </script>
5. Đối tượng Iterator do người dùng tự định nghĩa
Ta cũng có thể tạo đối tượng Iterator của riêng mình và gọi phương thức next() để truy cập các phần tử tiếp theo.
function vi_du(a) { let n = 0; return { next() { if(n < a.length) { return { value: a[n++], done: false } } return { value: undefined, done: true } } } } let a = ['J', 'a', 'v', 'a', 's','c','r','i','p', 't']; let iterator = vi_du(a); console.log(iterator.next()); console.log(iterator.next()); console.log(iterator.next()); console.log(iterator.next());
Trong chương trình trên, chúng ta đã tạo đối tượng Iterator của riêng mình. Hàm vi_du() trả về thuộc tính value và thuộc tính done . Mỗi lần phương thức next() được gọi, hàm vi_du() được thực thi một lần và hiển thị giá trị của một mảng. Cuối cùng, khi tất cả các phần tử của một mảng đã hết, thuộc tính done được đặt thành true , với giá trị là undefined .