이터레이터(Iterator)
이터레이터는 '반복자'라는 의미로, 이터러블(Iterable, 순회 가능한 자료구조)의 요소를 탐색하기 위한 포인터로서 next()함수를 가지고 있는 객체다.
단순하게 '컬렉션을 반복할 수 있게 하는 객체' 정도로 이해해본다.
지난 포스트에서도 알아봤듯이 Array, String, Map, Set, DOM이 이터러블이고, 이런 것을 반복할 수 있게 하는 것이 이터레이터다.
ex) Array.prototype[Symbol.iterator] ,String.prototype[Symbol.iterator], ...
1 2 3 4 5 6 7 8 | const iterable = ['a', 'b', 'c']; const iterator = iterable[Symbol.iterator](); // 이터레이터는 value, done 프로퍼티를 갖는 next()메소드 함수로 이터러블 순회가 가능하다. console.log(iterator.next()); // { value: 'a', done: false } console.log(iterator.next()); // { value: 'b', done: false } console.log(iterator.next()); // { value: 'c', done: false } console.log(iterator.next()); // { value: undefined, done: true } |
사용법도 간단하다. iterable 객체를 생성하고, 이터레이터를 받아와서, next()로 순회.
마찬가지로 value, done 프로퍼티 접근은 iterator.next().value / iterator.next().done
for~of 문
for~of문은 이터러블 객체를 순회할 때 사용할 수 있다.
for~of문은 next()로 전체를 순회한다. (done값이 true가 될 때까지)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | // 배열 for (const val of ['a', 'b', 'c']) { console.log(val);// "a","b","c" } // 문자열 for (const val of 'abc') { console.log(val);//"a","b","c" } // Map for (const [key, value] of new Map([['a', '1'], ['b', '2'], ['c', '3']])) { console.log(`key : ${key} value : ${value}`); // "key : a value : 1", "key : b value : 2", ... } // Set for (const val of new Set([1, 2, 3])) { console.log(val);// 1, 2, 3 } | cs |
for~in문이랑은 무엇이 차이가 날까?
=> for~of문은 값을 리턴한다.
for~in에서는 인덱스가 리턴되었지만 for~of는 값이 리턴되어 바로 값을 사용할 수 있다. (위에서는 val)
배열의 foreach쓰면 되는거 아닌가? -> foreach는 중간에 break, return을 할 수 없다.
1 2 | for (var i in 'string') { alert(i); } // 0, 1, 2, 3, 4, 5 for (var i of 'string') { alert(i); } // s, t, r, i, n, g | cs |
커스텀 이터러블(Custom iterable)
임의로 만든 객체는 이터러블이 아니다. 따라서 이터러블 객체를 만들어서 순회를 할 수 있어야 한다.
이터레이션 프로토콜이라고 해서 두 가지 조건을 만족하면 된다.
1. 어떤 객체는 [Symbol.iterator]를 구현하고 있고, iterator를 리턴해야 한다.
2. 그 iterator 객체는 next()를 구현하고 있고, value, done 프로퍼티를 갖는 객체를 반환해야 한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | var countdown = { max: 3, [Symbol.iterator]() { // Its ok to return 'this' because it implements the next function. return this; }, next() { if (this._max === undefined) { this._max = this.max; } if (this._max > -1) { return {value: this._max--}; // As long as you have a value } else { return {done: true}; // When you are out of values } } }; var v = countdown[Symbol.iterator](); console.log(v.next());//value : 3 console.log(v.next());//value : 2 console.log(v.next());//value : 1 console.log(v.next());//value : 0 console.log(v.next());//done : true |
참고사이트
https://blog.perfectacle.com/2017/04/22/es6-iterator/
https://www.zerocho.com/category/EcmaScript/post/575d4ea816eb22d05a7dc675
http://javascript.tutorialhorizon.com/2015/07/23/es6-iterators-part-2-creating-custom-iterators/
'Javascript > Javascript(ES6)' 카테고리의 다른 글
ES6 javascript로 자료구조 List 구현하기 (배웠으면 사용해보자!!) (0) | 2018.01.14 |
---|---|
ES6 자바스크립트 모듈 사용하기 (import, export) (0) | 2018.01.13 |
ES6 Class (클래스, Syntactic sugar, prototype을 이용하지만 문법적으로 예쁘게 만들어주는 class) (3) | 2018.01.09 |
Destructuring(디스트럭쳐링) - 배열과 객체의 값을 변수로 받는 방법 (0) | 2018.01.03 |
Rest 파라미터와 Spread 연산자 정리하기 (feat. 함수의 가독성을 높이는 방법) (0) | 2018.01.02 |