본 시리즈는 인프런 강의 함수형 프로그래밍과 JavaScript ES6+ ( 지식 공유자 : 유인동 님 ) 의 강의를 수강하면서 내용을 제 방식대로 포스팅하는 글입니다.
함수형 프로그래밍과 JavaScript ES6+ - 인프런 | 강의
ES6+와 함수형 프로그래밍을 배울 수 있는 강의입니다. 이 강좌에서는 ES6+의 이터러블/이터레이터/제너레이터 프로토콜을 상세히 다루고 응용합니다. 이터러블을 기반으로한 함수형 프로그래밍,
www.inflearn.com
사용자 정의 이터러블을 구현하면서 이터러블에 대해서 더 정확하게 알아보자
// iterable 이라고 하는 값을 직접 정의해보자
const iterable = {
// iterable 값은 Symbol.iterator 를 구현하고 있어야 됀다.
// Symbole.iterator 는 이터레이터를 반환 해야 한다.
[Symbol.iterator]() {
let i = 3;
// 이터레이터는 next 메소드를 가지고 있으며
return {
// next 는 value 와 done 을 가진 객체를 리턴해야한다.
next() {
return i == 0 ? { done: true } : { value: i--, done: false };
},
};
},
};
let iterator = iterable[Symbol.iterator]();
console.log(iterator.next()); // {value: 3, done: false}
console.log(iterator.next()); // {value: 2, done: false}
console.log(iterator.next()); // {value: 1, done: false}
console.log(iterator.next()); // {done: true}
for (const a of iterable) console.log(a); // 3 2 1
이터러블의 Symbol.iterator 가 구현되어 있기 때문에 for ... of 문에 들어갈수 있고,
안에서 Symbol.iterator 를 실행했을때 객체가 리턴되는것이고,
for ... of 문에서 내부적으로 next() 가 실행되면서 그 리턴문이 실행된다.
하지만 JS 이터러블의 모든 속성을 구현하지는 않았다.
const arr1 = [1, 2, 3];
// 잘 구현된 이터러블은, 이터레이터를 만들었을때
// 이터러블을 진행하다가 순회할수도 있고
// 그대로 값을 넣어도 처음부터 잘 실행된다
let iter1 = arr1[Symbol.iterator]();
// 이터러블의 이터레이터를 실행했을때, 자기 자신을 가지고 있을때
// well formed iterator, well formed iterable 이라고 할수있다.
console.log(iter1[Symbol.iterator]() === iter1); // true
iter1.next();
for (const b of iter1) console.log(b); // 2 3
다시 커스텀 이터러블을 구현하면,
const iterable = {
// iterable 값은 Symbol.iterator 를 구현하고 있어야 됀다.
// Symbole.iterator 는 이터레이터를 반환 해야 한다.
[Symbol.iterator]() {
let i = 3;
// 이터레이터는 next 메소드를 가지고 있으며
return {
// next 는 value 와 done 을 가진 객체를 리턴해야한다.
next() {
return i == 0 ? { done: true } : { value: i--, done: false };
},
// Symbol.iterator 를 실행했을때 리턴된 iterator 가
// 자기 자신또한 이터러블 이면서, 어디에서든 이터레이터로 만들었을때
// 이전까지 진행되어있던 자기 상태에서 계속해서 next() 를 할수 있도록 만들어 둔것이
// 잘 만든 이터레이터 인것이다.
[Symbol.iterator]() {
return this;
},
};
},
};
let iterator = iterable[Symbol.iterator]();
console.log(iterator.next()); // {value: 3, done: false}
console.log(iterator.next()); // {value: 2, done: false}
console.log(iterator.next()); // {value: 1, done: false}
console.log(iterator.next()); // {done: true}
// 이터러블도 순회가 되고, 이터레이터도 순회가 되고
// 일정부분 진행한 후에 실행해도 순회가 되도록 하는것이 잘 만든 이터레이터이다.
for (const a of iterable) console.log(a); // 3 2 1
for (const a of iterator) console.log(a); // ( 자기 자신이 반환되지 않았을 경우 ) TypeError iterator is not iterable
이 이터러블 / 이터레이터 프로토콜은 es6 에서 지원하는 내장 값만 이 프로토콜을 따르는 것이 아니다.
이미 많은 오픈소스 라이브러리, 어떤 JS 에서 순회가 가능한 형태의 값을 가진 값들은 대부분 이터러블 / 이터레이터 프로토콜을 따른다.
예로, 페이스북에서 만든 Eutable.js 의 경우에도 for of 문을 통해 순회할수 있도록 심볼 이터레이터가 구현되어 있다.
이런 오픈소스만 이터러블 / 이터레이터 프로토콜을 따르는 것이 아니라 JS 를 사용할수 있는 환경인 브라우저에서 사용할수 있는 Web APIs 들에 있는 구현되어 있는 많은 값들, 브라우저에서 사용할수 있는 DOM 과 관련된 값들 이라든지 여러 가지 값들도 이 이터러블 / 이터레이터 프로토콜을 따르고 있다.
예를 들면, NodeList 객체가 있다.
console.log(document.querySelectorAll("*")); // NodeList(n)[html,head,body...]
const all = document.querySelectorAll("*");
for (const c of all) console.log(c); // <html> <head> <body> ...
console.log(all[Symbol.iterator]()); // Array iterator{}
let iter2 = all[Symbol.iterator]();
console.log(iter2.next()); // {value : html, done: false}
console.log(iter2.next()); // {value : head, done: false}
console.log(iter2.next()); // {value : body, done: false}
NodeList 또한 이터러블 / 이터레이터 프로토콜을 따르고 있다 !
JS 에서 새롭게 바뀐 순회 그리고 이터러블 / 이터레이터 프로토콜은 굉장히 중요하다
'Javascript' 카테고리의 다른 글
제너레이터와 이터레이터 - JS ES6+ 함수형 프로그래밍 - 8 (1) | 2022.09.09 |
---|---|
전개 연산자 ( Spread Operator ) - JS ES6+ 함수형 프로그래밍 - 7 (3) | 2022.09.09 |
Array, Set, Map 을 통해 알아보는 이터러블 / 이터레이터 - JS ES6+ 함수형 프로그래밍 - 5 (1) | 2022.09.08 |
기존과 달라진 ES6 에서의 리스트 순회 - JS ES6+ 함수형 프로그래밍 - 4 (1) | 2022.09.08 |
고차 함수 - JS ES6+ 함수형 프로그래밍 - 3 (0) | 2022.09.08 |