작성자 : 배광식
검수자 : 장기효, 배광식
Iteration protocol
iterator의 next() 메서드를 통해 다양한 데이터 소스에 순차적으로 접근하는 방법을 제시
iterable
Symbol.iteratorproperty key로 사용하는 메서드를 구현하면 순회가능한 자료구조인 iterable이 된다.
class User {
constructor(id, name) {
this.id = id;
this.name = name;
}
}
// iterable
const seq = {
[Symbol.iterator]() {
let id = 0;
return {
next() {
return id < 5 ? { value: ++id, done: false } : { value: undefined, done:true };
}
}
}
};
iterator
iterable의 Symbol.iterator를 property key로 사용한 메서드는 iterator를 반환
iterable의 요소를 탐색하기 위한 포인터로서 next() 메서드를 갖는 객체
iterator object의 next() 메서드를 호출하면
value, doneproperty를 가지는 객체({value: object, done: boolean}) 반환
// ## User, seq는 위에 소스 참고
// iterator 반환
const idGen = seq[Symbol.iterator]();
// next() 호출
console.log(new User(idGen.next().value, 'jimmy')); // User { id: 1, name: 'jimmy' }
console.log(new User(idGen.next().value, 'jin')); // User { id: 2, name: 'jin' }
console.log(new User(idGen.next().value, 'josh')); // User { id: 2, name: 'jin' }
console.log(new User(idGen.next().value, 'sunny')); // User { id: 4, name: 'sunny' }
// value, done property를 가진다.
console.log(idGen.next()); // { value: 5, done: false }
console.log(idGen.next()); // { value: undefined, done: true }
for-of
- iterator의 next() 메서드 호출, done property가 true일 때까지 next() 메서드 호출
for(const value of seq) {
console.log(value); // 1 // 2 // 3 // 4 // 5
}
built-in iterables
prototype 객체에
Symbol.iterator메서드를 가지고 있는 객체Array, String, Map, Set, Dom data structures
Array 예제
- Array의 요소를 하나씩 반환
const iterable = [1, 2];
console.log(typeof iterable[Symbol.iterator]); // function
// iterator 반환
const iterator = iterable[Symbol.iterator]();
// next() 호출
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: undefined, done: true }
// for-of
for(const value of iterable) {
console.log(value); // 1 // 2
}
String 예제
- String의 문자를 하나씩 반환
const iterable = 'jimmy';
// iterator 반환
const iterator = iterable[Symbol.iterator]();
// next() 호출
console.log(iterator.next()); // { value: 'j', done: false }
console.log(iterator.next()); // { value: 'i', done: false }
console.log(iterator.next()); // { value: 'm', done: false }
console.log(iterator.next()); // { value: 'm', done: false }
console.log(iterator.next()); // { value: 'y', done: false }
console.log(iterator.next()); // { value: undefined, done: true }
// for-of
for(const value of iterable) {
console.log(value); // j // i // m // m // y
}
// spread operator
console.log([...iterable]); // [ 'j', 'i', 'm', 'm', 'y' ]
// destructuring assignmet : array의 value나 object의 property를 별개의 변수로 추출
const [first, second, third, ...rest] = iterable;
console.log(first, second, third, rest); // j i m [ 'm', 'y' ]
Generator
- generator object는 iterator이면서 iterable한 객체이다.
// generator
const generatorFnc = function* () {
yield 1;
yield 2;
};
// generator object
const genObj = generatorFnc();
// console.log(typeof generator);
// console.log(typeof genObj);
// iterator
console.log(typeof genObj.next); // function
// iterable
console.log(typeof genObj[Symbol.iterator]); // function
for(const value of genObj) {
console.log(value); // 1 // 2
}