Javascript와 Iterator
자바스크립트를 처음부터 다시 생각하고 공부해 보려고 한다.
ES6에서 Iterable protocol 이 추가 되었다.
프로그래밍 언어에서 iterator 란 배열이나 유사한 자료 구조의 내부의 요소를 순회(traversing)하는 객체이다. by Wiki
Iterable protocol에는 2가지 형태가 존재하는데, iterable 과 iterator 이 있다.
Iterable
iterable은 객체의 맴버를 반복할 수 있는 객체이다.
Javascript 에서 객체가 iterable 하기 위해서는, object 에는 [@@iterator] 메소드가 구현되어 있어야 한다.
Javascript 에서는 object property 에 Symbol.iterator 를 추가해야 한다.
obj[Symbol.iterator]
객체는 반드시 하나의 Symbol.iterator 만을 가질수 있다.
for of 를 이용해서 iterator의 값을 반복할 수 있다.
Javascript 에서 build-in object 중 iterable 를 가지고 있는 객체는 Array, TypedArray, String, Map, Set 가 있다.
Array.prototype[@@iterator]()
TypedArray.prototype[@@iterator]()
String.prototype[@@iterator]()
Map.prototype[@@iterator]()
Set.prototype[@@iterator]()
Iterator
iterator 은 객체를 next 메서드로 순환 할 수 있는 객체다.
iterator는 next() 메소드를 가지고 있고, next 메소드는 아래의 규칙에 따라 구현되어야 한다.
- next 메소드는 arguments 가 없다.
- next 메소드의 반환자는 done: boolean 과 value: any 를 포함하는 object 를 반환해야 한다.
- next 메소드의 반복이 끝날때 done 은 true 를 반환해야 한다.
Iterator 객체는 아래와 같이도 만들수 있다.
Javascript에서 Iterator 객체를 반환하는 함수는 아래와 같이 존재한다.
Javascript 에서 iterable 과 iterator 는 어떻게 구분할 수 있는가?
Object가 @@iterator 를 가지고 있다면, iterable 이다.
Object에서 next 메서드가 값을 반복하면서, {done, value} 를 반환한다면, iterator 이다.
그러므로, Javascript에서 generator object 는 규칙에 맞는 next 메서드를 가지고 있기 때문에, iterator이고, Object는 @@iterator 를 가지기 때문에 iterable 이다.
Generator function
Javascript에서 iterator 를 쉽게 구현할 수 있는 방법으로 generator 객체 가 있다.
그리고 이 generator 객체를 생성하는 방법은 GeneratorFunction 과 function* 이 있다.
GeneratorFuction은 global object 가 아니기 때문에, Object.getPrototypeOf 으로 정의 해야 한다.
function*은 컨텍스트 상태를 유지하는 함수이며, 호출시 반환자로 Generator 객체를 반환한다.
Generator은 iterator 규칙에 에 맞는 next() 메서드를 가지고 있기 때문에 iterator 객체 이다.
추가적으로 return(), throw() 를 포함한다.
Generator.next() 를 호출하면 generator function의 다음 yield 키워드를 만날때까지 동작하며, 만나면 해당 값을 전달한다.
만약 yield를 만나지 못하고 컨텍스트가 종료된다면, { value: undefined, done: true }를 반환한다.
next 함수에 arguments 를 전달한다면, yield 키워드에 그 값이 전달된다. 때문에 최초의 next arguments는 전달되지 않는다.
Spread 문법
Spread 문법을 이용하면 iterable 객체를 해체 할 수 있다.
var text = '123';console.log([...text]);// ["1", "2", "3"]