1. Symbol

 

심볼(Symbol)은 ES6에서 추가된 7번째 타입으로 변경 불가능한 원시 타입이다.

 

Symbol 값은 객체의 프로퍼티 키로 사용할 수 있다. Symbol 값은 유일한 값이므로 Symbol 값을 키로 갖는 프로퍼티는 다른 어떠한 프로퍼티와도 충돌하지 않는다.

const o = {};
const symbol = Symbol('my-symbol');
o[symbol] = 123;
o.symbol = 'test';

console.log(o); // { symbol: 'test', [Symbol(my-symbol)]: 123 }
console.log(o[symbol]); // 123
console.log(o.symbol); // test

 

 

1-1. Symbol.iterator

 

Symbol.iterator를 프로퍼티 key로 사용한 메소드 가지고 있으면 자바스크립트 엔진은 이 객체가 이터레이션 프로토콜을 따르는 것으로 간주하고 이터레이터로 동작하도록 한다.

 

Array
Array.prototype[Symbol.iterator]

String
String.prototype[Symbol.iterator]

Map
Map.prototype[Symbol.iterator]

Set
Set.prototype[Symbol.iterator]

DOM data structures
NodeList.prototype[Symbol.iterator] HTMLCollection.prototype[Symbol.iterator]

arguments
arguments[Symbol.iterator]

 

2. iterable

 

iterable은 객체의 맴버를 반복할 수 있는 객체이다. 객체가 iterable 하기 위해서는, object 에는 [@@iterator] 메소드가 구현되어 있어야 한다.

 

객체는 반드시 하나의 Symbol.iterator 만을 가질수 있고, for of 를 이용해서 iterator의 값을 반복할 수 있다.

 

const obj = {
  a: 1,
  b: 2,
  [Symbol.iterator]() {
    this.current = this.a;
    return this;
  },
  next() {
    if (this.current === this.a) {
      this.current = this.b;
      return { done: false, value: this.a };
    }
    if (this.current === this.b) {
      this.current = undefined;
      return { done: false, value: this.b };
    }
    return { done: true, value: undefined };
  },
};

for (let i of obj) {
  console.log(i);
}
// 1
// 2

 

3. iterator

 

iterator 은 객체를 next 메서드로 순환 할 수 있는 객체다. iterator는 next() 메소드를 가지고 있고, next 메소드는 아래의 규칙에 따라 구현해야 한다.

 

  • next 메소드는 arguments 가 없다.
  • next 메소드의 반환자는 done: boolean 과 value: any 를 포함하는 object 를 반환해야 한다.
  • next 메소드의 반복이 끝날때 done 은 true 를 반환해야 한다. (아니면 무한 루프로 진행)
const obj = {
  a: 1,
  b: 2,
  [Symbol.iterator]() {
    this.current = this.a;
    return this;
  },
  next() {
    if (this.current === this.a) {
      this.current = this.b;
      return { done: false, value: this.a };
    }
    if (this.current === this.b) {
      this.current = undefined;
      return { done: false, value: this.b };
    }
    return { done: true, value: undefined };
  },
};

const oIter = obj[Symbol.iterator]();
console.log(oIter.next()); // { done: false, value: 1 }
console.log(oIter.next()); // { done: false, value: 2 }
console.log(oIter.next()); // { done: true, value: undefined }

 

4. generator

 

ES6에서 도입된 제너레이터 함수는 이터러블을 생성하는 함수이다. 제너레이터 함수를 사용하면 이터레이션 프로토콜을 준수해 이터러블을 생성하는 방식보다 간편하게 이터러블을 구현할 수 있다. 또한 제너레이터 함수는 비동기 처리에 유용하게 사용된다.

 

function* test() {
  yield 1;
  yield 2;
}

const iter = test(); // 함수 실행 시 제너레이터 반환
console.log(iter.next()); // { value: 1, done: false }
console.log(iter.next()); // { value: 2, done: false }
console.log(iter.next()); // { value: undefined, done: true }

 

제너레이터 함수를 실행하면 제너레이터를 반환하는데 제너레이터는 이터러블이면서 동시에 이터레이터인 객체이다. (즉, Symbol.iterator 메소드를 소유한 이터러블이다)

 

제너레이터 함수는 일반 함수와는 다르게 동작을 한다. 제너레이터 함수는 일반 함수와 같이 함수의 코드 블록을 한 번에 실행하지 않고 함수 코드 블록의 실행을 일시 중지했다가 필요한 시점에 재시작할 수 있는 특수한 함수이다. (yield 키워드로 일시 정지하고, next로 재시작하고 다음 yield 키워드를 만날 때까지 진행한다.

 

4-1. generator 함수의 활용

 

1. iterable의 구현

Symbol.iterator를 직접 구현할 필요가 없어진다. yield 키워드를 활용해서 보다 쉽게 이터러블을 구현할 수 있다.

 

2. 비동기 처리

비동기 실행을 보장하는 코드를 작성할 수 있다.

 

- 참고

poiemaweb.com/es6-generator#42-%EB%B9%84%EB%8F%99%EA%B8%B0-%EC%B2%98%EB%A6%AC

 

Generator | PoiemaWeb

ES6에서 도입된 제너레이터(Generator) 함수는 이터러블을 생성하는 함수이다. 제너레이터 함수를 사용하면 이터레이션 프로토콜을 준수해 이터러블을 생성하는 방식보다 간편하게 이터러블을 구�

poiemaweb.com

 

 

** 내용 출처

1. poiemaweb.com/es6-generator

2. medium.com/@pks2974/javascript%EC%99%80-iterator-cdee90b11c0f

3. medium.com/@pks2974/javascript%EC%99%80-%EC%8B%AC%EB%B3%BC-symbol-bbdf3251aa28

+ Recent posts