Symbol ?

Jinux·2022년 8월 29일
0
post-thumbnail

다들 아시다시피 자바스크립트는 6개의 타입을 가지고 있습니다.

  • Boolean
  • null
  • undefined
  • Number
  • String
  • Object

객체 타입인 Object를 제외한 모든 타입은 원시 타입이죠. ES6에서 원시타입에 심볼이 새로 추가되었습니다. 이 심볼은 주로 이름의 충돌 위험이 없는 객체의 프로퍼티 키를 만들기 위해 사용한다고 합니다.

1. Symbol의 생성

Symbol은 Symbol() 함수로 생성되는데요. 이때 생성된 Symbol은 객체가 아니라 변경 불가능한 원시 타입입니다. 또 String, Number, Boolean과 같이 래퍼 객체를 생성하는 생성자 함수와는 달리 new 연산자를 사용하지 않습니다.

let symbol = Symbol();

console.log(symbol); // Symbol()

Symbol() 함수에 문자열을 인자도 전달하고 이 문자열은 어떠한 영향을 주지 않습니다. 그냥 설명의 역할이죠.

let symbol = Symbol('이름');

console.log(symbol); // Symbol(이름)

2. Symbol의 사용

그렇다면 이 symbol을 어떻게 사용할 수 있을까요?

다들 아시다시피 객체의 프로퍼티 키는 문자열로 만들 수 있습니다. Symbol 값도 객체의 프로퍼티 키로 사용할 수 있는데요. Symbol은 유일한 값이므로 다른 어떠한 프로퍼티와도 충돌하지 않습니다.

const obj ={};

const nameSymbol = Symbol('이름');
obj[nameSymbol] = 'jinwoo';

console.log(obj); // { [Symbol(이름)]: 'jinwoo' }
console.log(obj[nameSymbol]); // jinwoo

문득 궁금한 점이 생각나는데요 만약 obj[nameSymbol]의 값을 직접 obj[Symbol('이름')]으로 바꾸어 호출하면 어떻게 될까요?

const obj ={};

const nameSymbol = Symbol('이름');
obj[nameSymbol] = 'jinwoo';

console.log(obj[Symbol('이름')]); // undefined

undefined가 나오는 모습입니다. 앞에서 설명한 부분이 이렇게 직접 찍어보니 이해가 되는데요. Symbol은 각각의 유일한 값으로 같은 인자를 준다하더라도 다른 Symbol임을 알 수 있었습니다.

사실 인자는 앞서 설명한듯이 설명의 역할뿐인거죠.

3. Symbol.for

앞서 알아본 Symbol 함수는 매번 다른 Symbol 값을 생성했습니다. 그렇다면 키를 공유하고 싶을 때는 저 객체를 지니고 있어야할까요?

// 전역 Symbol 레지스트리에 foo라는 키로 저장된 Symbol이 없으면 새로운 Symbol 생성
const s1 = Symbol.for('foo');
// 전역 Symbol 레지스트리에 foo라는 키로 저장된 Symbol이 있으면 해당 Symbol을 반환
const s2 = Symbol.for('foo');

console.log(s1 === s2); // true

Symbol.for 메소드는 인자로 전달받은 문자열을 키로 사용하여 Symbol 값들이 저장되어 있는 전역 Symbol 레지스트리에서 해당 키를 검색합니다. 검색이 되었다면 Symbol 값을 반환하고 없다면 해당 키로 전역 Symbol 레지스트리에 저장한후 Symbol 값을 반환합니다.

즉, Symbol.for 메소드를 사용하면 하나의 Symbol을 생성하여 키를 통해 같은 Symbol을 공유할 수 있게됩니다.

반면에 Symbol 함수를 통해 생성된 Symbol 값은 키가 없죠.

const shareSymbol = Symbol.for('myKey');
const key1 = Symbol.keyFor(shareSymbol);
console.log(key1); // myKey

const unsharedSymbol = Symbol('myKey');
const key2 = Symbol.keyFor(unsharedSymbol);
console.log(key2); // undefined

마무리

심볼은 객체의 고유한 프로퍼티 키로 사용할 수 있을 것 같다는 생각이 듭니다. 또 Symbol.for 메소드로 키를 공유, 생성할 수 있구요.

Symbol의 중요한 특성이 하나 더 있는데 바로 Symbol.iterator를 프로퍼티 key로 사용하는 메소드가 있다면 이 객체는 이터레이터로 동작한다는 것입니다.

이터레이터는 간단히 설명하자면 next 메소드를 사용해 순회하며 값을 반환할 수 있는 객체인데요. 다음 포스팅에서 이터레이터션 프로토콜에 대해 좀 더 자세하게 알아보고 Symbol.iterator를 이해해보겠습니다.

참고: https://poiemaweb.com/es6-symbol

0개의 댓글