본문 바로가기
JavaScript/함수형 프로그래밍과 JavaScript ES6+

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

by 정ㅇr 2021. 11. 3.
728x90

1) ES5 vs ES6 리스트 순회 비교

ES5에서의 리스트 순회

const list = [1, 2, 3];
for (var i = 0; i < list.length; i++) {
    console.log(list[i]);
}

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

ES6에서의 리스트 순회

for (const a of list) {
    console.log(a);
}

for (const a of str) {
    console.log(a);
}

ES6에서 확실히 간결해진게 눈에 보인다.

 

2) 이터러블/이터레이터 프로토콜 (Array, Set, Map)

// Array
const arr = [1, 2, 3];
for (const a of arr) console.log(a);

// Set
const set = new Set([1, 2, 3]);
for (const a of set) console.log(a);

// Map
const map = new Map([['a', 1], ['b', 2], ['c', 3]]);
for (const a of map) console.log(a);

console 창에서 arr[0] 이런식으로 값을 불러내면 Array만 값을 불러낼 수 있고,

나머지 Set, Map은 값을 꺼내지 못한다.

 

Symbol.iterator : 어떤 객체의 키로 사용될 수 있음

Array, Set, Map은 각각 Symbol.iterator에 구현되어 있는 함수를 가지고 있다.

 

Array, Set, Map은 자바스크립트 안에 있는 내장 객체로서, 이터러블/이터레이터 프로토콜을 따름

 

- 이터러블 : 이터레이터를 리턴하는 [Symbol.iterator]()를 가진 값

- 이터레이터 : { value, done }이라는 키 값을 가진 객체를 리턴하는 next()를 가진 값

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}

이런 식으로 next() 메소드를 사용해서 value 값과 done을 리턴하게 됨

Array는 이터레이터를 리턴하는 이터러블 객체이며, for.. of 순회를 할 수 있기 때문에 이터러블/이터레이터 프로토콜을 따른다고 할 수 있다.

 

- 이터러블/이터레이터 프로토콜 : 이터러블을 for...of, 전개 연산자 등과 함께 동작하도록한 규약

 

// Array
const arr = [1, 2, 3];
for (const a of arr) console.log(a);

// Set
const set = new Set([1, 2, 3]);
for (const a of set) console.log(a);

// Map
const map = new Map([['a', 1], ['b', 2], ['c', 3]]);
for (const a of map) console.log(a);
// 콘솔창
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}

두 코드를 함께 살펴보면 for.. of 문은 iterator.next()를 계속 진행하면서, value 값을 a로 반환하고, done이 true가 될 때 멈추게 되는 동작 방식을 가지고 있다.

 

Set도 Array와 마찬가지로 set[Symbol.iterator](); 라는 이터레이터에서, next()를 계속 진행하면서 for.. of 문이 도는 것.

 

Map은 [Symbol.iterator]()를 사용해서 출력해보면, key값에 해당되는 value값을 나타낸다.

또한, Map은 keys라는 함수를 가지고 있는데, 아래와 같이 key 값만 담은 iterator를 반환하고, next를 사용해서 출력해보면, value 값에 key 값만 담아준다.

// Map
const map = new Map([['a', 1], ['b', 2], ['c', 3]]);
for(const a of map.keys()) console.log(a);

코드에서는 이런 식으로 키 값만 뽑을 수 있게 된다.

 

이 외에도 values(), entries() 라는 함수도 있다.

// Map
const map = new Map([['a', 1], ['b', 2], ['c', 3]]);
for(const a of map.keys()) console.log(a); // a, b, c 출력
for(const a of map.values()) console.log(a); // 1, 2, 3 출력
for(const a of map.entries()) console.log(a); // map에 들어있는 각 객체 출력

이러한 함수들을 사용하면, MapIterator 로 이터레이터가 출력된다.

위와 같이 이터레이터로 만든 값은 다시 Symbol.iterator 값을 가지고 있는 것을 볼 수 있다.

이 값을 가지고 있기 때문에 for .. of 문을 사용해서 값을 출력할 수 있는 것이다.

반응형

댓글