ES6에서의 순회와 이터러블: 이터레이터 프로토콜

윤성민·2020년 7월 17일
0

함수형 프로그래밍에서 리스트 순회는 매우 중요하다.

자바스크립트가 ES6이 되면서 리스트 순회가 매우 많이 바뀌었다.

기존과 달라진 ES6에서의 리스트 순회

const log = console.log
// ES6 이전
const list = [1, 2, 3];
// 기존에는 리스트의 길이와 키에 의존하여 순회를 하였다.
for (var i = 0; i<list.length; i++){
    log(list[i]); // 1 2 3
}

const str = 'abc';
for (var i = 0; i<str.length; i++){
    log(str[i]); // a b c
}

// ES6
// 문법이 보다 간결해졌고 선언적으로 리스트를 순회한다.
for (const a of list){
    log(a); // 1 2 3
}
for (const a of str){
    log(a); // a b c
}

Array를 통해 알아보기

log('Arr ---------------')
const arr = [1, 2, 3];
let iter1 = arr[Symbol.iterator]();
iter1.next();
for (const a of arr) log(a); // 1 2 3
arr[0] // 1
log(arr[Symbol.iterator]) // f values() { [native code]} 무언가 들어있다.
// arr[Symbol.iterator] = null;
// for (const a of arr) log(a); // Uncaught TypeError: arr is not iterable
let iterator = arr[Symbol.iterator](); // undefined
iterator.next(); // {value: 1, done: false}
iterator.next(); // {value: 2, done: false}
iterator.next(); // {value: 3, done: false}
iterator.next(); // {value: undefined, done: true}
iterator.next(); // {value: undefined, done: true}

for of 구문은 인덱스로 접근하는 것이 아닌 Symbol.iterator 이터레이터를 통해 동작한다.

i

Set을 통해 알아보기

log('Set ---------------')
const set = new Set([1, 2, 3]);
for (const a of set) log(a); // 1 2 3
set[0] // undefined
set[Symbol.iterator] //  f values() { [native code]} 무언가 들어있다.

set은 키로 접근을 할 수 없다. for of는 키로 접근하는 게 아니라는 것을 알 수 있다.

Symbol.iterator

Map을 통해 알아보기

log('Map ---------------')
const map = new Map([['a', 1],['b', 2], ['c', 3]]);
for (const a of map) log(a); // ["a", 1] ["b", 2] ["c", 3]
map[0] // undefined
map[Symbol.iterator] //  f values() { [native code]} 무언가 들어있다.
for (const a of map.keys()) log(a);
for (const a of map.values()) log(a);
for (const a of map.entries()) log(a);

map도 키로 접근이 불가능하다. set과 같이 map도 for of는 키로 접근하는 게 아니라는 것을 알 수 있다.

이터러블 / 이터레이터 프로토콜

  • 이터러블 : 이터레이터를 리턴하는 [Symbol.iterator]() 를 가진 값
  • 이터레이터 : { value, done } 객체를 리턴하는 next() 를 가진 값
  • 이터러블 / 이터레이터 프로토콜 : 이터러블을 for... of, 전개 연산자 등과 함께 동작하도록 한 규약
const arr = [1, 2, 3]
let iterator = arr[Symbol.iterator](); // undefined
iterator.next() // {value:1, done: false}
iterator.next() // {value:2, done: false}
iterator.next() // {value:3, done: false}
iterator.next() // {value: undefined, done: true}


const arr2 = [1, 2, 3];
let iter1 = arr[Symbol.iterator]();
iter1.next();
for (const a of iter1) log(a); // 2 3

for of는 Symbol.iterator를 순회하면서 value를 반환한다.

출처

인프런 함수형 프로그래밍과 JavaScript ES6+ 정리

profile
기록은 기억보다 강하다.

0개의 댓글