Strong Root



  한 collection 에서 각각의 아이템을 순회하는 것은 매우 흔한 작업이다.


  Iterator 와 Generator 는 iteration 에 대한 직접적인 적용 및 커스터마이징 메커니즘을 제공한다.







ES6 에서의 Iterator (Iterator in ES6)


Iterator 는 새로운 문법이나 built-in 이 아니라 프로토콜(약속)이다.


이 프로토콜은 몇 가지 규칙만 준수한다면 어떠한 객체에서도 구현될 수 있다.











Iterator 프로토콜 (The iterator protocol)


Iterable 한 객체가 되려면 Symbol.iterator 를 Key 로 갖는 속성이 반드시 존재해야 한다:


Property

Value

[Symbol.iterator]

  Iterator 프로토콜을 준수하는 객체를 리턴하며 인자가 없는 함수




다음 규칙에 따라 next() 메서드를 구현한 객체를 iterator 라고 한다:


Property

Value

next

 아래의 두 속성을 가지는 객체를 리턴하며 인자가 없는 함수:


 1. done (boolean)

     * iterator 가 순회를 모두 마쳤을 경우 true

     * iterator 가 순회할 다음 value 가 존재할 경우 false

 2. value - iterator 에 의해 리턴될 값. done 이 true 일 경우 생략 가능




Iterable 하며 Iterator 프로토콜을 만족하는 예시 코드:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var someObject = {};
 
...
 
someObject[Symbol.iterator] = function () {
  var num = 1;
 
  return {
    next: function() {
      return num < 4 ?
        {value: num++, done: false} :
        {done: true};
    }
  };
};
 
...
 
for (let value of someObject) {
  console.log(value);
}
// 1
// 2
// 3
cs











Generators


커스텀 iterator 는 유용하지만, 그 내부 상태를 유지하기 위한 매우 세심한 관리를 필요로 한다.


Generator 는 이에 대한 강력한 대안이다: 내부 상태를 스스로 유지하는 하나의 함수만 작성하면 된다.



Generator 는 iterator 를 위한 factory 함수의 일종이다.


하나 이상의 yield expression 을 가지며 function* 문법을 사용하는 함수를 Generator 라고 한다.



Generator 예시 코드:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var someObject = {};
 
...
 
someObject[Symbol.iterator] = function* () {
  var num = 1;
 
  while (num < 4) {
    yield num++;
  }
};
 
...
 
for (let value of someObject) {
  console.log(value);
}
// 1
// 2
// 3
cs











특이한 예제 코드 (Examples)


무한 iterator (infinite iterator):


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function idMaker(){
    var index = 0;
    
    return {
       next: function(){
           return {value: index++, done: false};
       }
    };
}
 
var it = idMaker();
 
console.log(it.next().value); // '0'
console.log(it.next().value); // '1'
console.log(it.next().value); // '2'
// ...
cs




Generator 를 사용한 무한 iterator (Infinite iterator with a generator):


1
2
3
4
5
6
7
8
9
10
11
12
function* idMaker(){
    var index = 0;
    while(true)
        yield index++;
}
 
var gen = idMaker();
 
console.log(gen.next().value); // '0'
console.log(gen.next().value); // '1'
console.log(gen.next().value); // '2'
// ...
cs











출처


https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators