자바스크립트 Iterator 개념 정리

blackbell·2020년 5월 14일
3

javascript

목록 보기
1/6

Javascript에서의 Interface, iterator 객체의 개념에 대해서 살펴보자. 😊

Interface

  1. 인터페이스란 사양에 맞는 값과 연결된 속성키의 셋트
  2. 어떤 Object라도 인터페이스의 정의를 충족시킬 수 있다.
  3. 하나의 Object는 여러 개의 인터페이스를 충족할 수 있다.

An 'interface' is a set of property keys whose associated values match a specific specification. Any object that provides all the properties as described by an interface's specification conforms to that interface. An interface is not represented by a distinct object. There may be many separately implemented objects that conform to any interface. An individual object may conform to multiple interfaces.

🗒스펙문서 (https://tc39.es/ecma262/#sec-iteration)

예를 들어, Test Interface 정의를 test라는 키를 갖고, 값으로 문자열을 받아 Boolean을 리턴하는 함수가 온다고 하자.

{
	test(str){return true;}
}

그럼 다음과 같이 간단한 Test Interface의 정의를 만족하는 객체를 만들 수 있을 것이다.

Iterator Interface

  1. next라는 키를 갖는다.
  2. 값으로 인자를 받지 않고, IteratorResultObject를 반환하는 함수가 온다.
  3. IteratorResultObject는 value와 done이라는 key를 가지고 있다.
  4. done은 계속 반복할 수 있을지 없을지에 대한 Boolean값을 반환다.
{
    next() {
      	return {value: 1, done: true};
    } 
}

Iterable Interface

  1. Symbol.iterator라는 키를 갖는다.
  2. 값으로 인자를 받지 않고, Iterator Object를 반환하는 함수가 온다.
{
    [Symbol.iterator](){
    	return {
           next() {
             return {value: 1, done: true};
           }
        }
    }
}

다음과 같은 예를 만들 수도 있음.

const iter = {
  [Symbol.iterator]() {
    return this;
  },
  arr: [1, 2, 3, 4, 5],
  next() {
    return {
      done: this.arr.length === 0,
      value: this.arr.pop()
    };
  }
};


for (const item of iter) {
  console.log(item);
}

/*
출력
5
4
3
2
1
*/
const iter = {
  [Symbol.iterator]() {
    return this;
  },
  arr: [1, 2, 3, 4, 5],
  next() {
    return {
      done: this.arr.length === 0,
      value: this.arr.pop()
    };
  }
};

const [a, ...b] = iter;
console.log(a);

/*
출력
5
*/

iterable interface의 정의를 충족 시키면 다음과 같이 array destructuring같은 언어 스펙을 사용할 수 있다.

for ~ of 의 루프대신 직접 호출을 통한 반복

// 문자열도 iterable이다.
const str = '문자열입니다.';

const iterator = str[Symbol.iterator]();

while(true) {
  const iteratorResultObject = iterator.next();
  if (iteratorResultObject.done) break;
  console.log(iteratorResultObject.value);
}

이터러블과 유사 배열

비슷해 보이지만 아주 다른 용어 두 가지가 있다. 헷갈리지 않으려면 두 용어를 잘 이해하고 있어야 한다.

  • 이터러블(iterable)은 위에서 설명한 바와 같이 메서드 Symbol.iterator가 구현된 객체임.
  • 유사 배열(array-like)은 인덱스와 length 프로퍼티가 있어서 배열처럼 보이는 객체임.

Array.from

범용 메서드 Array.from는 이터러블이나 유사 배열을 받아 진짜 Array를 만들어준다. 이 과정을 거치면 이터러블이나 유사 배열에 배열 메서드를 사용할 수 있다.


// 유사 배열
const arrayLike = {
  0: 1,
  1: 2,
  length: 2
};

console.log(Array.from(arrayLike).pop());

// iterable
const iter = {
  [Symbol.iterator]() {
    return this;
  },
  arr: [1, 2, 3, 4, 5],
  next() {
    return {
      done: this.arr.length === 0,
      value: this.arr.pop()
    };
  }
};


/*
pop을 하면서 반복하는 iterable 객체이므로
Array.from(iter)
 = [5,4,3,2,1]
*/

console.log(Array.from(iter).pop());

// 출력
// 2
// 1

출처

코드스피츠
https://ko.javascript.info/iterable

profile
알고 싶은게 많은 프론트엔드 개발자입니다.

0개의 댓글