iterator와 for of 의 관계

KHW·2021년 8월 10일
0

Javascript 지식쌓기

목록 보기
69/95

for of를 실행한다면?

배열은 Symbol.iterator를 실행한 대상을 value로 떨어지는 값을 출력한다.

1) for of 일반 동작

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

1, 2, 3 차례로 출력

2) for of의 Symbol.iterator를 null로

const arr = [1, 2, 3];
arr[Symbol.iterator] = null;
for (const a of arr) console.log(a);

TypeError: arr is not iterable

3) for of의 iter1.next() 한번 실행

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

{ value: 1, done: false } , 2 , 3 가 각각 출력


for of와 iterator 관계

ES6에서 나온 for of는 iterator를 만족시키는 배열, map , set과 같은 것에서 iterable을 통해 next메소드를 반복적으로 진행하며 value를 뽑아 출력하는 것이다.
이것은 iterator와 관련이 없는 for in에는 적용되지 않는다.

const arr = [1, 2, 3];
let iter1 = arr[Symbol.iterator]();
for (const a in iter1) console.log(a);
  • for in을 적용했을때 아무 결과도 출력되지 않는다.

iterable 함수구현

  • 기본 object코드
const object = {
  ["a"]() {},
  ["b"]: () => {},
};
console.log(object, object["a"], object["b"]);
  • { a: [Function: a], b: [Function: b] } [Function: a] [Function: b] 결과로 같다.

  • iterable코드

const iterable = {
  [Symbol.iterator](val) {
    return {
      next() {
        return val == 0 ? { done: true } : { value: val--, done: false };
      },
      [Symbol.iterator]() {
        return this;
      },
    };
  },
};
let iterator = iterable[Symbol.iterator](3);

for (const a of iterator) console.log(a);
  1. next()를 반환해야한다.
  2. [Symbol.iterator]()는 자기자신을 리턴해야한다.
const a = [1, 2, 3];
let iter = a[Symbol.iterator]();
console.log(iter[Symbol.iterator]()[Symbol.iterator]() == iter);
console.log(iter[Symbol.iterator]() == iter);
for (const p of iter) console.log(p);
  • 즉, 해당 콘솔이 둘다 true이다.

적용

해당 iterable은 js뿐만 아니라 HTML태그에 대해서도 iterable형태가 가능하다 => for of 를 태그에서도 사용할 수 있다.

전개연산자

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

즉, 전개연산자 또한 iterable과 연관되어 있다.


1) 다른 전개연산자

const a = (...list)=>{
    console.log(list)
}

a(1,2,3) 		// [1, 2, 3]

1,2,3 == ...list이므로
list는 배열이고 이를 ...한게 1,2,3이 되므로
list는 [1,2,3]이다.


2) 다른 전개연산자


const ex = (f) => (a, ..._) => {
  console.log(a, _, f);			//1 [ 2, 3, 4 ] [Function (anonymous)]
};
const mult = ex((a, b) => a * b);
mult(1, 2, 3, 4);

제너레이터

이터레이터이자 이터러블을 생성하는 함수

function* gen() {
  yield 1;
  if (false) yield 2;
  yield 3;
  return 100;
}

let iter = gen();
console.log(iter[Symbol.iterator]() == iter);
console.log(iter.next());
console.log(iter.next());
console.log(iter.next());

for (const a of gen()) console.log(a);
  • 결과
true
{ value: 1, done: false }
{ value: 3, done: false }
{ value: 100, done: true }
1
3

제너레이터 함수는 앞에 *를 붙인다.
yield를 통해 순회할 수 있는 값을 조작한다.
if문을 통해 yield 처리도 가능하다.
return을 통해 done:true일 때 value를 next()를 이용해 확인은 가능하나
for of같은 순회에서는 확인이 불가능하다.
즉, 제너레이터를 통해 우리가 필요한 이터러블 형태를 만들어 처리할 수 있다.

  • +a 제너레이터를 한 대상의 ...를 하면 해당 value의 모음이 된다.
    => ...iter == 1 3
profile
나의 하루를 가능한 기억하고 즐기고 후회하지말자

0개의 댓글