ES2015 iterable 로 date range 만들어보기
iterable protocol은 객체를 for..of
같은 구문에서 사용할 수 있게 해준다. 객체에 Symbol.iterator
을 이름으로 하는 메소드를 구현하면 이 프로토콜을 만족한다.
메소드 이름을 Symbol.iterator
으로 하기 위해서는 computed property syntax 를 쓰면 된다. [Symbol.iterator]
요약하자면, iterable 은
- 객체를
for .. of
구문을 통해 순회할 수 있게 해준다. - spread operator (
...
) 에서도 쓸 수 있게 해준다. Symbol.iterator
메소드를 구현하면 되고, 이 메소드에서는 iterator 를 만들어서 리턴한다.
대략적인 코드 틀은 이러게 나온다고 보면 될 것 같다.
const anIterable = {
//some codes
[Symbol.iterator]() {
return {
next() {
//some codes
return {
value: //some value,
done: //true/false
}
}
};
}
};
iterable 까지 보고 나니, moment-range 의 이 코드가 이해가 되었다. https://github.com/rotaready/moment-range/blob/master/lib/moment-range.js#L61
참고
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols
- https://codeburst.io/a-simple-guide-to-es6-iterators-in-javascript-with-examples-189d052c3d8e
사용 코드
const moment = require('moment');
const start = moment('2018-10-15', 'YYYY-MM-DD');
const end = moment('2018-11-22', 'YYYY-MM-DD');
const moment_daterange = function (start, end) {
let next = start;
return {
[Symbol.iterator]() {
return {
next: () => {
if (!next.isAfter(end)) {
const ret = next.clone();
next.add(1, 'd');
return {value: ret, done: false}
} else {
return {value: undefined, done: true};
}
}
}
}
};
};
const dateIterator = moment_daterange(start, end);
for(let d of dateIterator){
console.log(d.format(moment.HTML5_FMT.DATE));
}
하나씩 개별적으로 알아본 iterator, iterable, generator 의 관계에 대한 정리는 내일 하도록 하자.