어떤 객체가 String, Array 같이 순회 (iteration) 할 수 있는 타입이 아니더라도, JavaScript에서 순회가 가능한 (iterable) 객체로 만드는 방법이 있다. 이를 Iteration protocol 이라하며 interable, iterator 를 만드는 2개의 규칙(protocol) 을 기술하고 있다.
iterable 규약에 순응하는 객체는 for...of
syntax, Spread syntax, destructuring
syntax 등에서 사용이 가능해진다.
1. iterable 정의
iterable로 정의하기 위해서는 아래와 같은 내용을 객체 또는 prototype chain내 객체에서 아래 내용을 구현하여야 한다.
[Symbol.iterator] (혹은 @@iterator)
란 Property로 메소드를 구현해야한다.- 해당 메서드는 iterator 객체를 반환하여야 한다.
2. iterator 정의
iterable 에서 [Symbol.iterator]
호출에 의해 반환되는 iterator 순회할 때 마다
결과를 반환한다. 결과를 반환하기 위해 iterator은 아래의 프로퍼티를 구현한다.
next
란 이름의 메소드 구현 (필수)
next
메소드는 1개 혹은 0개의 파라미터를 전달 받을 수 있으며,IteratorResult
인터페이스를 준수하는 객체를 반환한다.- 반환값이
undefined
의 경우{ done: false, value: undefined}
와 동일
- 반환값이
return(value)
,throw(exception)
메소드 구현 (옵션)
return()
:IteratorResult
인터페이스를 준수하는 객체를 반환한다. 이후next
메소드는 더 호출되지 않는다.throw()
IteratorResult
인터페이스를 준수하는 객체를 반환한다. 필요한 경우 이 메소드르 호출하여 iterator에게 오류가 감지되었음을 알린다.
2.1 IteratorResult
Interface
done
: true/false로 반복이 끝났는지를 나타낸다. 끝났으면 true로 설정value
: 현재 반환되는 값을 설정
예시
iterable 구현 일반
1 | let i = 0; |
iterable 의 return()
구현
1 | const customIterator = { |
Node.js 의 /lib/events.js
에서 구현 (실 활용 예제)
iterator의 return()
함수를 정의하여 리소스를 해제하는데 사용한다.
1103 | return() { |
iteration 도중 오류를 핸들링하기 위해 throw(err)
함수를 정의한다.
1107 | throw(err) { |
iteration을 위한 next() 호출이 될때 IteratorResult
형식으로 현재 값을 반환한다.
1071 | const iterator = ObjectSetPrototypeOf({ |
next() 호출에 대해 undefined를 반환함으로써 iteration이 종료되었음을 알린다.
1094 | // If the iterator is finished, resolve to done |