Web/JavaScript

[JavaScript] 모던 자바스크립트 Deep Dive 33장 - Symbol

어징베 2023. 2. 3. 19:19


1. 심벌이란?

ES6에서 도입된 7번째 데이터 타입으로 변경 불가능한 원시 타입의 값


2. 심벌 값의 생성

Symbol 함수를 호출하여 생성

const mySymbol = Symbol();
console.log(typeof mySymbol);

// 확인할 수 없다.
console.log(mySymbol); // Symbol()

생성된 심벌 값은 외부로 노출되지 않아 확인할 수 없으며, 다른 값과 절대 중복되지 않는 유일무이한 값이다.

const mySymbol1 = Symbol('mySymbol'); 
const mySymbol2 = Symbol('mySymbol');
console.log(mySymbol1 === mySymbol2); // false

심벌 값도 객체처럼 접근하면 암묵적으로 래퍼 객체를 생성한다.

console.log(mySymbol.description); // mySymbol
console.log(mySymbol.toString()); // Symbol(mySymbol)

심벌 값은 암묵적으로 문자열이나 숫자 타입으로 변환되지 않는다.

const mySymbol = Symbol();

console.log(mySymbol + ""); // Cannot convert a Symbol value to a string
console.log(+mySymbol); // Cannot convert a Symbol value to a string

단, 불리언 타입으로 변환된다.


2-1 Symbol.for / Symbol.keyFor 메서드

Symbol.for 메서드는 인수로 전달받은 문자열을 키로 사용하여 키와 심벌 값의 쌍들이 저장되어 있는 전역 심벌 레지스트리에서 해당 키와 일치하는 심벌 값을 검색한다.

  • 검색에 성공하면 새로운 심벌 값을 생성하지 않고 검색된 심벌 값을 반환한다.
  • 검색에 실패하면 새로운 심벌 값을 생성하여 Symbol.for 메서드의 인수로 전달된 키로 전역 심벌 레지스트리에 저장한 후, 생성된 심벌 값을 반환한다.
// 전역 심벌 레지스트리에 mySymbol이라는 키로 저장된 심벌 값이 없으면 새로운 심벌 값을 생성
const s1 = Symbol.for('mySymbol');
// 전역 심벌 레지스트리에 mySymbol이라는 키로 저장된 심벌 값이 있으면 해당 심벌 값을 반환
const s2 = Symbol.for('mySymbol');

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

Symbol.keyFor(s1); // mySymbol

const s2 = Symbol('foo');

Symbol.keyFor(s2); // undefined

3. 심벌과 상수

값에는 특별한 의미가 없고 상수 이름 자체에 의미가 있는 경우, 다른 변수 값과 중복될 수도 있기 때문에 중복될 가능성이 없는 유일무이한 심벌 값을 사용할 수 있다.


4. 심벌과 프로퍼티 키

객체의 프로퍼티 키는 빈 문자열을 포함하는 심벌 값으로 만들 수 있으면 동적으로 생성할 수 있다.

대괄호사용

const obj = {
    // 심벌 값으로 프로퍼티 키를 생성
    [Symbol.for('mySymbol')]: 1
};

obj[Symbol.for('mySymbol')]; // 1

심벌 값은 유일무이한 값이므로 심벌 값으로 프로퍼티 키를 만들면 다른 프로퍼티 키와 절대 충돌하지 않는다.


5. 심벌과 프로퍼티 은닉

const obj = {
    // 심벌 값으로 프로퍼티 키를 생성
    [Symbol.for('mySymbol')]: 1
};

console.log(Object.keys(obj)); // []
console.log(Object.getOwnPropertySymbols(obj)); // [Symbol(mySymbol)]