-
[JS] Iterable/Iterator 프로토콜백수의 개발/웹 2021. 8. 19. 00:42
Iterator Protocol
Array, Map, Set와 같은 컬렉션 내 각 항목 처리는 매우 흔한 연산이다.
iterator protocol을 통해 이러한 컬렉션을 더 잘 사용할 수 있다.
iterator는 두 개의 속성( value, done)을 반환하는 next() 메소드 사용하여 객체의 iterator protocol을 구현한다.
실제 구현되어있는 iterator를 실행해보자.
const arr = ['a', 'b', 'c', 'd', 'e']; const iter = arr[Symbol.iterator](); console.log(iter.next()) // { value: "a", done: false } console.log(iter.next()) // { value: "b", done: false } console.log(iter.next()) // { value: "c", done: false } console.log(iter.next()) // { value: "d", done: false } console.log(iter.next()) // { value: "e", done: false } console.log(iter.next()) // { value: undefined, done: true }
이와 같이 iterator에서 next를 호출하여 위와 같이 실행할 수 있다.
이러한 iterator가 내부적으로 어떻게 구현될 수 있는지 알아보자.
Array의 iterator 구현해보기
Symbol.customIterator = Symbol.for('customIterator'); Array.prototype[Symbol.customIterator] = function() { const self = this; let i = 0; return { next: function() { if (i === self.length) return { value: undefined, done: true }; const value = self[i]; i++; return { value: value, done: false }; }, [Symbol.customIterator]: self[Symbol.customIterator] } }
위와 같이 직접 구현해보면 기존 iterator와 동일한 결과를 얻을 수 있다.
const arr = ['a', 'b', 'c', 'd', 'e']; const customIter = arr[Symbol.customIterator](); console.log(customIter.next()) // { value: "a", done: false } console.log(customIter.next()) // { value: "b", done: false } console.log(customIter.next()) // { value: "c", done: false } console.log(customIter.next()) // { value: "d", done: false } console.log(customIter.next()) // { value: "e", done: false } console.log(customIter.next()) // { value: undefined, done: true }
iterable 규약
이러한 iterable이 구현된 것들은 for...of, 전개 연산자 등과 함께 동작하도록 규약되어있다.
const arr = [1, 2, 3, 4]; for(const value of arr) { console.log(value); } const [first, second, ...rest] = arr; const arrarr = [...arr, ...arr]; console.log(first); // 1 console.log(second); // 2 console.log(rest); // [3, 4] console.log(arrarr); // [1, 2, 3, 4, 1, 2, 3, 4]
generator
generator와 yield를 통해 이러한 iterator를 만들 수 있다.
function *gen() { yield 'a'; yield 'b'; yield 'c'; } const iter = gen(); console.log(iter.next()); // { value: "a", done: false } console.log(iter.next()); // { value: "b", done: false } console.log(iter.next()); // { value: "c", done: false } console.log(iter.next()); // { value: undefined, done: true }
function *을 통해 iterator의 next메서드들이 생성이 되고, yield를 통해 (value, doen)이 생성이 된다고 보면된다.
generator에 대한 내용은 추후 더 자세하게 다루어보도록 하겠다.
'백수의 개발 > 웹' 카테고리의 다른 글
Javascript Symbol 이란? (0) 2021.08.18 var, let, const의 특징과 차이점 (0) 2021.08.11 CSS로 다양한 도형 만들기 - Clippy (0) 2020.08.20 CSS Transform 알아보기(2) - translate (0) 2020.04.07 CSS Transform 알아보기(1) - 기본개념 (0) 2020.04.06