JavaScript와 Iterator

2020. 11. 23. 15:17·프로그래밍 언어/JavaScript

ES2015에서 Iterable Protocol이 추가되었습니다.

Iterable Protocol에는 2가지 형태가 존재하는데, iterable과 iterator가 있습니다.

 

Iterable

iterable은 객체의 멤버를 반복할 수 있는 객체입니다.

iterable은 자바스크립트 객체의 요소들에 대해 반복되는 행동(예를 들어, for .. of 구문에서 어떤 값들이 루프를 돌고 있는가)을 정의할 수 있도록 해줍니다.

JavaScript에서 객체가 iterable하기 위해서는, object에는 [@@iterator] 메서드가 구현되어 있어야 합니다.

따라서 임의로 우리가 객체를 만들고 iterable하게 만들고 싶다면, object 프로퍼티에 Symbol.iterator를 추가해야 합니다.

 

객체는 반드시 하나의 Symbol.iterator 만을 가질 수 있습니다.

const iterable = new Object();

// obj[Symbol.iterator] 함수는 iterator 객체를 반환합니다.
iterable[Symbol.iterator] = function* () {
  yield 1;
  yield 2;
  yield 3;
};
// 전개 연산자를 이용해서 iterator의 값을 반복할 수 있습니다.
console.log([...iterable]); // 1 2 3
// for ... of 를 이용해서 iterator의 값을 반복할 수 있습니다.
for(var value of iterable) {
    console.log(value); // 1 2 3
}

객체가 iterated 될 때, @@iterator 메서드가 인자 없이 호출되고, @@iterator가 반환하는 iterator는 iterated되는 값들을 얻기 위해 사용됩니다.

@@iterator 메서드는 호출한 후 iterable한 객체를 반환하므로 generator 함수라고도 할 수 있습니다.  

Iterator

iterator 는 객체를 next 메서드로 순환할 수 있는 객체입니다.

iterator는 next() 메소드를 가지고 있고, next 메소드는 아래의 규칙에 따라 구현되어야 합니다.

  1. next 메소드는 arguments 가 없습니다.
  2. next 메소드는 done: boolean 과 value: any 를 포함하는 object 를 반환해야 합니다.
  3. next 메소드의 반복이 끝날때 done 은 true 를 반환해야 합니다.
const iterator = '132'[Symbol.iterator]();
iterator.next(); // {value: "1", done: false}
iterator.next(); // {value: "3", done: false}
iterator.next(); // {value: "2", done: false}
iterator.next(); // {value: undefined, done: true}

 

 

iterator 객체는 아래와 같이 만들 수 있습니다.

const obj = {};
// iterator를 생성하는 함수
// iterator는 이 함수의 반환값입니다.
const counter = count => (
  (i = 0) => ({
    next: () => (
      (i++ < count) ?
      { value: i, done: false } :
      { value: 0, done: true }
    )
  })
);
obj[Symbol.iterator] = counter(3);
console.log([...obj]); // [1, 2, 3]

 

 

Iterable 과 Iterator 의 구분

Object가 @@iterator 를 가지고 있다면, iterable 입니다.

Object에서 next 메서드가 값을 반복하면서, {done, value} 를 반환한다면, iterator 입니다.

 

Iteration protocols 의 예시

 

Javascript 에서 built-in object 중 iterable 를 가지고 있는 객체는 Array, TypedArray, String, Map, Set 가 있으며 이들의 메서드 중 일부는 iterator 객체를 반환합니다. 대표적으로 Object.entries( ), Object.keys( ), Object.values( ) 메서드 등이 있습니다. 

  • Object.entries( ) : 전달된 파라미터 객체가 가지는 (열거 가능한) 속성 [key, value] 쌍의 배열을 리턴합니다.
  • Object.keys( ) : 전달된 파라미터 객체가 가지는 (열거 가능한) 속성의 key 이름들로 이루어진 배열을 리턴합니다.
  • Object.values( ) : 전달된 파라미터 객체가 가지는 (열거 가능한) 속성의 값들로 이루어진 배열을 리턴합니다.

 

const arr = ['1', '2', '3'];

console.log([...arr.entries()]);
// [[0, '1'], [1, '2'], [2, '3']];
console.log([...arr.keys()]);
// [0, 1, 2];
console.log([...arr.values()]);
// ['1', '2', '3'];

const map = new Map([[1, '1'], [2, '2'], [3, '3']]);

console.log(map.entries());
// MapIterator {1 => "1", 2 => "2", 3 => "3"}
console.log(map.keys());
// MapIterator {1, 2, 3}
console.log(map.values());
// MapIterator {"1", "2", "3"}

const set = new Set([1, 2, 3]);

console.log(set.entries());
// SetIterator {1, 2, 3}
console.log(set.keys());
// SetIterator {1, 2, 3}
console.log(set.values());
// SetIterator {1, 2, 3}

문자열의 기본적인 iterator는 문자열의 요소들을 하나씩 반환합니다.

전개 연산자 또한 기본적으로 동일한 iteration protocol을 사용합니다.

let someString = 'hello';

let iterator = someString[Symbol.iterator]();
console.log(iterator + ''); // "[object String Iterator]"

console.log(iterator.next()); // {value: 'h', done: false }
console.log(iterator.next()); // {value: 'e', done: false }
console.log(iterator.next()); // {value: 'l', done: false }
console.log(iterator.next()); // {value: 'l', done: false }
console.log(iterator.next()); // {value: 'o', done: false }
console.log(iterator.next()); // {value: undefined, done: true }

console.log([...someString]); // ['h', 'e', 'l', 'l', 'o']

 

 

우리가 직접 @@iterator를 정의하여 iteration 특성을 재정의해봅시다.

// need to construct a String object explicitly to avoid auto-boxing
let someString = new String('hello');

someString[Symbol.iterator] = function () {
  return {
    // this is the iterator object, returning a single element (the string "bye")
    next: function () {
      return this._first ? {
        value: 'bye',
        done: (this._first = false)
      } : {
        done: true
      }
    },
    _first: true
  };
};

console.log([...someString]); // ["bye"]
console.log(someString + ''); // "hello"

 

 

 

출처 : MDN - Iteration protocols

'프로그래밍 언어 > JavaScript' 카테고리의 다른 글

[JavaScript] for, foreach, filter, map, reduce 기능 및 퍼포먼스의 차이  (2) 2022.09.24
Generator  (0) 2020.11.23
Node와 Element  (0) 2020.11.22
DOM, CSSOM, BOM은 무엇일가?  (0) 2020.11.22
자바스크립트 모듈(Module)  (0) 2020.11.21
'프로그래밍 언어/JavaScript' 카테고리의 다른 글
  • [JavaScript] for, foreach, filter, map, reduce 기능 및 퍼포먼스의 차이
  • Generator
  • Node와 Element
  • DOM, CSSOM, BOM은 무엇일가?
rondeveloper
rondeveloper
  • rondeveloper
    Ron's learning record
    rondeveloper
  • 전체
    오늘
    어제
    • 분류 전체보기 (102)
      • k8s (2)
      • AWS (1)
      • 리눅스 (5)
      • Docker (8)
      • 라이브러리 & 프레임워크 (14)
        • React (2)
        • NestJS (8)
        • Spring (0)
        • Django (3)
        • FastAPI (1)
      • 웹 (2)
        • Nginx (1)
      • 프로그래밍 언어 (29)
        • HTML (0)
        • CSS (0)
        • JavaScript (21)
        • Python (3)
        • Node.js (0)
        • TypeScript (4)
        • Java (1)
      • Today I learned (9)
      • 알고리즘 (9)
        • 백준 (0)
        • 프로그래머스 (8)
        • 개념 (1)
      • 티끌모아 태산 (5)
        • 하루에 영단어 하나씩 (5)
        • 독서 (0)
      • 시행착오 (3)
      • 데이터베이스 (2)
        • MySQL (0)
      • 컴퓨터 과학 (8)
        • 네트워크 (2)
        • 운영체제 (0)
        • 데이터베이스 (2)
        • 자료구조 (4)
      • 포트폴리오 (4)
        • JJINCAFE IN SEOUL (4)
        • CODEUNICORN (0)
      • 회고 (0)
      • CICD (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    mysql
    배열
    도커
    코딩테스트
    FastAPI
    기초
    네트워크
    컨테이너
    iterable
    nestjs
    레벨2
    조인
    redis
    typeorm
    스택
    Python
    IP 주소
    Kubectl
    Docker
    javascript
    생활코딩
    모듈
    Kubernetes
    리눅스
    프로그래머스
    반복문
    Til
    자바스크립트
    django
    typescript
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
rondeveloper
JavaScript와 Iterator
상단으로

티스토리툴바