-
[Functional] 순회와 이터러블programing/Language 2019. 7. 15. 16:43
안녕하세요, Einere입니다.
(ADblock을 꺼주시면 감사하겠습니다.)
ES6에서의 리스트 순회
for of
// array const arr = [1, 2, 3]; for(const e of arr) console.log(e); // set const set = new Set([1, 2, 3]); for(const e of set) consol.elog(e); // map const map = new Map([['a', 1], ['b', 2], ['c', 3]]); for(const e of map) consol.log(e); for(const e of map.entries()) console.log(e); // ["a", 1], ["b", 2], ["c", 3] 출력 for(const e of map.keys()) console.log(e); // a, b, c 출력 for(const e of map.values()) console.log(e); // 1, 2, 3 출력
이터러블(iterable)/이터레이터(iterator) 프로토콜
이터러블을 for of, 전개연산자 등과 함께 동작하도록 만든 규약. 혹은 모든 객체를 이터러블로 만들 수 있는 프로토콜.
이터러블
이터레이터를 반환하는 [Symbol.iterator]() 를 가진 값.
Symbol.iterator는 Iterator를 반환하는 함수이다.
이터레이터
{value, done}객체를 반환하는 next() 를 가진 값.
Iterator.next는 {value:any, done:boolean}객체를 반환한다.
사용자 정의 이터러블
// 3 2 1 을 순회하는 이터러블을 정의합니다 const iterable = { // Symbol.iterator라는 속성을 가져야 한다 [Symbol.iterator]() { let i = 3; // next라는 속성을 가진 객체, 즉 이터레이터를 반환한다 return { // next 함수는 {value, done}을 반환한다 next() { // i가 0이라면 순환을 그만둔다 // 아니라면 순환을 계속한다 return { value : i--, done: i === 0 }; }, // 동일한 이터레이터를 반환한다 // well-formed iterable [Symbol.iterator]() { return this; } } } };
// 함수 호출 스택을 출력하는 함수와 기록하는 함수를 가진 객체를 생성 및 반환하는 함수 function buildFunctionCallLogObject() { let stack = []; const reverseIterable = { [Symbol.iterator]() { let i = stack.length; return { next() { i--; return { done: i < 0, value: stack[i] } }, [Symbol.iterator]() { return this; } } } }; return { // 함수 호출 스택을 순회하며 출력한다 printExecutionSequence() { for(e of reverseIterable) console.log(e); }, // 함수 호출 스택에 함수 호출 기록을 저장한다 logExecutionSequence() { let errorStack = new Error().stack || ''; let log = errorStack.split('\n')[2].trim(); stack.push(log); } } } // 비구조화 할당 const {printExecutionSequence, logExecutionSequence} = buildFunctionCallLogObject();
잘 정의된 이터러블(well-formed iterable)
잘 정의된 이터레이터는, 자기 자신을 반환하는 Symbol.iterator을 가지고 있는 이터레이터입니다.
위 사진과 같이, 배열 arr의 이터레이터인 iter1은 자기자신을 Symbol.iterator의 반환값으로 가집니다.
따라서 iter1과 iter2는 동일합니다.
잘 정의된 이터레이터는 특성상 자신의 상태를 기억하는 이터레이터를 언제든지 사용할 수 있습니다.
예를 들어, iter1.next()를 한 뒤 for(const e of iter1) { console.log(e); }를 하게 된다면 2와 3만 출력됩니다.
이런 이터레이터를 가진 이터러블을 잘 정의된 이터러블라고 합니다.
전개연산자
const arr = [1, 2, 3]; console.log(...arr); // 1 2 3 출력 const arr1 = [4, 5, 6]; console.log([...arr, ...arr1]); // [1, 2, 3, 4, 5, 6] 출력
전개연산자도 이터러블을 이용합니다.
이러한 특성을 이용해 위와 같이 유동적인 파라미터를 다룰 수 있습니다.
참고
마이클 포거스, 『함수형 자바스크립트 : 새롭고 올바른 자바스크립트 프로그래밍 기법』, 한빛미디어(2014).
유인동, 인프런 - 함수형 프로그래밍과 JavaScript ES6+
https://medium.com/@chanakyabhardwaj/es6-reverse-iterable-for-an-array-5dae91c02904
'programing > Language' 카테고리의 다른 글
[Functional] map, filter, reduce (0) 2019.07.15 [Functional] 제네레이터와 이터러블 (0) 2019.07.15 [Functional] 평가와 일급, 고차함수 (0) 2019.06.25 [JS] 블로그 드래그 방지 해제 (0) 2019.06.12 [HTML, JS] ES6문법을 활용한 모듈 export, import (0) 2019.05.04 댓글