Iterator in javascript

Một số khái niệm

Iterator và iterator result

Iterator là 1 object có thể lấy ra lần lượt các iterator result, implement method next() và bằng cách gọi method next() có thể trả về iterator result. Giá trị trả về này là 1 object có chứa thuộc tính done cho biết có thể đã kết thúc chuỗi iterated sequence hay chưa và thuộc tính value để biểu thị giá trị.

Dưới đây là 1 ví dụ minh họa về iterator và iterator result

var it = {}; // iterator
it.next = function(){
    var r = { value: 5, done: false }; // iterator result
    return r;
};

Iterable object

Iterable object là 1 object có chứa iterator. Cụ thể khi gọi [Symbol.iterator]() sẽ trả về iterator của object đó

var it = {}; // iterator
it.next = function(){
    var r = { value: 5, done: false }; // iterator result
    return r;
};
var obj = {}; // iterable object
obj[Symbol.iterator] = function(){
    return iterator;
};

Sử dụng iterator

Tạo 1 iterable object

Xét 1 ví dụ đơn giản tạo 1 iteratable object có thể lấy ra các số nguyên từ 1 đến 5.

Dựa theo các khái niệm đã nói ở trên, ta cần tạo 1 object obj mà khi gọi obj[Symbol.iterator] sẽ trả về iterator. Iterator đố cần định nghĩa method next để có thể lấy được phấn tử tiếp theo.

var obj = {}; // iterable object
obj[Symbol.iterator] = function(){
    var it = {}; // iterator
    var count = 1;
    it.next = function(){
        var r = (count <= 5)
            ? { value: count++,   done: false }
            : { value: undefined, done: true };
        return r; // iterator result
    };
    return it;
};

Lâý danh sách các giá trị từ iterable object

Sử dụng iterable object được định nghĩa ở ví dụ trước, ta có thể in ra danh sách các giá trị từ iterable object bằng cách loop cho đến khi iterator result có thuộc tính donetrue

var iterator = obj[Symbol.iterator]();
var iteratorResult;
while(true){
    iteratorResult = iterator.next();
    if(iteratorResult.done) break;
    console.log(iteratorResult.value);
}

Kết quả

1
2
3
4
5

Ta cũng có thể viết ngắn gọn hơn bằng cách sử dụng for

for(var v of obj) console.log(v);

Kết quả trả về là tương đương

Builtin iterables

Array

Array cung cấp những method keys, entries để thu thập giá trị cũng như index của các phần tử trong mảng

var obj = ["A", "B", "C"];
for(var v of obj) console.log(v);
for(var v of obj.keys()) console.log(v);
for(var v of obj.entries()) console.log(v);
A
B
C
0
1
2
[0, "A"]
[1, "B"]
[2, "C"]

String

Chúng ta cũng có thể loop qua và in ra từng kí tự của String

var str = "abc";
for(var v of str) console.log(v);
a
b
c

Kiểu dữ liệu khác

Ngoài array, string, Javascript còn cung cấp nhiều kiểu dữ liệu iterable khác như Map, Set, Generator

Một số ứng dụng cụ thể

Toán tử

Sử dụng toán tử ... chúng ta có thể khởi tạo mảng từ các iterable object

var ary = [0, "A", false];
var str = "xyz";
var arr = [...ary, ...str];
console.log(arr);
=> [0, "A", false, "x", "y", "z"]

Truyền iterable object như tham số

var nums = [104, 101, 108, 108, 111];
console.log( Math.max(...nums) );
console.log( String.fromCharCode(...nums) );
=>
111
hello

Phép gán

Javascript cho phép cú pháp [a ,b ,c ] = iterable để gán lần lượt giá trị của iterable object vào các biến theo thứ tự

var [a, b, c] = "hai";
console.log(c+b+a);
=> iah