JavaScript Symbol 타입: 고유 식별자 생성 방법

작성일 :

JavaScript Symbol 타입: 고유 식별자 생성 방법

JavaScript에서 다양한 데이터 타입이 존재하지만, 그 중에서도 Symbol 타입은 특히 주목받는 타입 중 하나입니다. Symbol은 ECMAScript 6(ES6)에서 처음 도입된 원시 데이터 타입으로, 고유하고 변경 불가능한 값을 생성할 수 있습니다. 이를 활용하면 객체의 고유한 프로퍼티 키를 만들거나, 기존 코드에 영향을 주지 않고 확장을 할 수 있습니다. 이 글에서는 Symbol 타입의 특징, 사용 방법, 그리고 실제 사례를 통해 Symbol을 효과적으로 활용하는 방법을 살펴보겠습니다.

Symbol 타입의 특징

Symbol 타입은 다음과 같은 특징을 지닙니다:

  1. 고유성: 생성된 심볼 값은 전역에서 유일합니다. 동일한 설명(description)을 사용해 생성하더라도 각 Symbol 값은 독립적입니다.
  2. 변경 불가능: 심볼 값은 생성 후 변경할 수 없습니다. 이는 원시 데이터 타입의 특징을 따릅니다.
  3. 속성 키로 사용: 심볼은 객체의 속성 키로 사용할 수 있습니다. 이는 객체의 다른 속성과 충돌 없이 독립적인 속성을 추가할 수 있게 해줍니다.
javascript
const symbol1 = Symbol('description');
const symbol2 = Symbol('description');

console.log(symbol1 === symbol2); // false

위 예제에서 symbol1symbol2는 동일한 설명을 사용했음에도 불구하고, 서로 다른 고유한 값으로 생성됩니다.

Symbol 생성 방법

Symbol은 함수 호출을 통해 생성합니다. Symbol 함수는 네 가지 형태로 사용할 수 있습니다:

  1. 기본 생성: 아무 인자 없이 Symbol을 생성합니다.
  2. 설명과 함께 생성: 설명을 제공하여 디버깅이나 로그용으로 사용합니다.
  3. 전역 심볼 레지스트리를 사용한 생성: Symbol.for()와 Symbol.keyFor()를 통해 전역 심볼을 생성 및 조회합니다.
  4. 내장 심볼: 표준에 정의된 다양한 내장 심볼을 사용합니다.

기본 생성

기본 생성은 아주 간단합니다. 아무 인자 없이 실행하면 고유한 심볼을 생성합니다.

javascript
const sym = Symbol();
console.log(typeof sym); // 'symbol'

설명과 함께 생성

설명을 포함하여 생성하면 디버깅 시 유용하게 사용할 수 있습니다.

javascript
const symWithDesc = Symbol('uniqueDescription');
console.log(symWithDesc.toString()); // 'Symbol(uniqueDescription)'

전역 심볼 레지스트리를 사용한 생성

전역 심볼 레지스트리는 전역에서 공유되는 심볼 값들을 저장합니다. Symbol.for()Symbol.keyFor()를 사용하여 전역 심볼을 생성하고 조회할 수 있습니다.

javascript
const globalSym = Symbol.for('globalSymbol');
const sameGlobalSym = Symbol.for('globalSymbol');

console.log(globalSym === sameGlobalSym); // true
console.log(Symbol.keyFor(globalSym)); // 'globalSymbol'

내장 심볼 사용

ES6에서는 다양한 내장 심볼도 함께 제공됩니다. 예를 들어, Symbol.iterator는 객체의 반복자를 정의하는 데 사용됩니다.

javascript
const iterable = {
  [Symbol.iterator]() {
    let step = 0;
    return {
      next() {
        step++;
        if (step <= 5) {
          return { value: step, done: false };
        }
        return { value: undefined, done: true };
      }
    };
  }
};

for (const value of iterable) {
  console.log(value); // 1 2 3 4 5
}

Symbol의 실제 사례

Symbol은 다양한 상황에서 유용합니다. 다음은 그 사용 사례들입니다:

객체 속성 키 보완

Symbol을 사용하면 객체 속성 키의 충돌을 방지할 수 있습니다.

javascript
const UNIQUE_KEY = Symbol('uniqueKey');
const obj = {
  [UNIQUE_KEY]: 'Unique Value'
};

console.log(obj[UNIQUE_KEY]); // 'Unique Value'

숨겨진 속성

때로는 객체의 특정 속성을 외부에 노출시키고 싶지 않을 때가 있습니다. 이때 Symbol을 사용하면 해당 속성을 숨길 수 있습니다.

javascript
const PRIVATE = Symbol('privateProperty');
class MyClass {
  constructor() {
    this[PRIVATE] = 42;
  }
  getPrivate() {
    return this[PRIVATE];
  }
}

const myInstance = new MyClass();
console.log(myInstance.getPrivate()); // 42
console.log(myInstance.PRIVATE); // undefined

결론

JavaScript의 Symbol 타입은 고유한 식별자를 생성하고, 객체의 속성 충돌을 방지하며, 코드 확장성을 높이는 데 매우 유용합니다. 특별히 전역 심볼 레지스트리와 내장 심볼을 활용하면 더욱 강력한 코드 작성이 가능합니다. Symbol을 잘 활용하여 모듈성 있고, 안전하며, 유지보수하기 쉬운 코드를 작성할 수 있습니다.