자바스크립트의 기본형은 총 6가지이다.

  • Boolean
  • Null
  • Undefined
  • Number
  • String
  • Symbol

나만 그런지는 잘 모르겠지만…. Symbol은 써본적도 없고 뭔지도 잘 모르겠다.

iterator를 정의할 때 Symbol을 사용하는것 같아서 생각난김에 정리해보려고 한다.

Symbol

Symbol은 유일하고 변경 불가능(immutable)한 기본값(primitive value)이다.

  • Symbol은 객체 속성의 Key값으로 사용할 수 있다. (String, Symbol 사용 가능하다)

  • Symbol은 atom이라고도 부른다.

  • Symbol은 열거형 (enum)과 비슷하다)

Symbol 비교

const key1 = Symbol("key");
const key2 = Symbol("key");

console.log(key1 === key2);

const obj = {};
obj[key1] = 10;
obj[key2] = 10;
console.log(obj); // { Symbol(key): 10, Symbol(key): 10 }
console.log(obj[Symbol(10)]); // undefined
console.log(obj[key1]); // 10

console.log(Object.keys(obj)); // []
console.log(Object.getOwnPropertyNames(obj)); // []
console.log(Object.getOwnPropertySymbols(obj)); // { Symbol(key), Symbol(key) }

for (let i in obj) {
  console.log(i); // 아무것도 출력되지 않음. for문 실행되지 않음
}
  • Symbol은 항상 다른값을 반환한다.

  • Symbol은 for...in으로 열거 불가능하다.

  • Symbol은 getOwnPropertySymbol로만 조회 가능하다.

전역 심볼 레지스트리

Symbol()은 일반적인 스코프를 따르지만, Symbol.for()를 사용하여 생성한 심볼은 전역 심볼 레지스트리 리스트에 심볼을 만든다.

Symbol.for()는 심볼이 있을 경우 해당 심볼을 반환하고, 없을 경우 새로운 심볼을 만든다.

const globalSymbol1 = Symbol.for("global");
const globalSymbol2 = Symbol.for("global");
console.log(globalSymbol1 === globalSymbol2); // true

const innerSymbol1 = Symbol.for("inner");
const funcScope = () => {
  const innerSymbol2 = Symbol.for("inner");
  console.log(innerSymbol1 === innerSymbol2); // true
};
funcScope();

built-in 심볼

정의할 수 있는 Symbol 외에 내장(built-in) 심볼들이 존재한다. Symbol의 속성들을 이용해 built-in 심볼들에 접근할 수 있다.

  • Symbol.iterator 예시

    const obj = {};
    
    for (let i of obj) {
      // Uncaught TypeError: obj is not iterable
      console.log(i);
    }
    
    const iterableObj = {};
    
    iterableObj[Symbol.iterator] = function* () {
      yield 1;
      yield 2;
      yield 3;
    };
    
    for (let i of iterableObj) {
      console.log(i); // 1, 2, 3 출력
    }
    console.log([...iterableObj]);
    // expected output: Array [1, 2, 3]
    

    for...of 문법은 열거 가능한 속성이 있는 객체를 반복하는데, [Symbol.iterator]를 이용하여 내장 심볼에 접근하여 iterable protocol을 따르는 객체를 반환하도록 할 수 있다.

그래서…. Symbol이 뭘까……???