순회와 이터러블

MyeonghoonNam·2021년 8월 9일
0

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

  • 기존의 리스트 순회
const list = [1, 2, 3];
for( var i = 0; i< list.length; i++){
	log(list[i]);
}

/*유사 배열 순회*/
const str = 'abc';
for( var i = 0; i< str.length; i++){
	log(str[i]);
}
  • ES6 리스트 순회
for(const a of list){ //for of로 리스트 안에 있는 값(a)을 순회한다.
	log(a);
}
for(const a of str){
	log(a);
}

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

이터러블을 for...of, 전개 연산자 등과 함께 동작하도록 한 규약을 말한다.

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

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

// Map
const map = new Map([['a',1], ['b', 2], ['c', 3]]);
for (const a of map)log(a)
  • 이터러블 : 이터레이터를 리턴하는 Symbol.iterator() 를 가진 값

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

  • map이 아닌 map.values(), map.keys(), map.entries()역시 정상동작을 하는데, 이는 해당 함수를 통해 반환되는 값들도 Iterator 형태임을 알 수 있다.

  • Array, Set, Map은 Javascript 내장객체로써 이터러블/이터레이터 프로토콜을 따른다.


사용자 정의 이터러블

const iterable = {
  [Symbol.iterator]() {
    let i = 3;
    return {
      next(){
        return i == 0 ? {done: true}:{value: i--, done:false};
      },
      [Symbol.iterator](){return this;} //자기자신을 return 해준다.
    }
  }
}

let iterator = iterable[Symbol.iterator]();
iterator.next(); // 주석 처리하며 비교해보자.

for(const a of iterator) console.log(a);

좋은 이터러블이란 ?

  • 이터레이터를 만들어서 순회를 할 때 잘 동작 한다.
  • 일부 진행한 이후에는 진행된 결과 이후의 값들로 진행이 된다.

well-formed Iterator

이터레이터 역시 Symbol.iterator를 가지고 있고 이 Symbol.iterator를 실행한 값은 자기자신이다.

const arr2 = [1, 2, 3];
let iter = arr2[Symbol.iterator]();
log(iter[Symbol.iterator]() == iter2)// true

DOM 역시 Iterator를 통해 순회가 가능하다

for( const a of document.querySelectorAll('*')) log(a) //dom ... dom

querySelectorAll의 반환값(NodeList)역시 Symbol.iterator가 구현되어 있고 규약을 따르기에 for...of 사용을 통해 순회가 가능하다.

전개 연산자

const a = [1, 2];
a[Symbol.iterator] = null; 
log([...a, ...[3,4]);//Uncaught TypeError: a is not iterable

const b = [1, 2];
log([...a, ...[3,4]); // [1, 2, 3, 4]

a[Symbol.iterator] = null; 으로 iterator를 null로 해주면 에러가 발생한다.

즉, 전개연산자 역시 iterable 프로토콜을 따른다는 의미가 된다.

profile
꾸준히 성장하는 개발자를 목표로 합니다.

0개의 댓글