🚀 94sssh
Published on

2024.08.19

[딥다이브] - 33. 7번째 데이터 타입 Symbol

33.1. 심벌이란?

ES6에서 도입된 7번째 데이터 타입으로 변경 불가능한 원시 타입의 값, 심벌 값은 다른 값과 중복되지 않는 유일무이한 값이다.

33.2. 심벌 값의 생성

33.2.1. Symbol 함수

심벌 값은 Symbol 함수를 호출하여 생성한다. 리터럴 표기법으로 생성할 수 없고 Symbol 함수를 호출해야 한다. 생성된 심벌 값은 외부에 노출되지 않아 확인할 수 없으며, 다른 값과 중복되지 않는 유일무이한 값이다.

const mySymbol = Symbol()
console.log(typeof mySymbol) // symbol

console.log(mySymbol) // Symbol()

Symbol 함수는 new 연산자와 함께 호출하지 않는다.
Symbol 함수에 선택적으로 문자열을 인수로 전달할 수 있지만, 심벌 값 생성에 어떠한 영향도 주지 않는 설명, 디버깅 용도이다.

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

33.2.2. Symbol.for / Symbol.keyFor 메서드

Symbol.for은 인수로 전달받은 문자열을 키로 사용해 전역 심벌 레지스트리에서 해당 키와 일치하는 심벌 값을 검색한다.

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

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

Symbol.keyFor을 사용하면 전역 심벌 레지스트리에 저장된 심벌 값의 키를 추출할 수 있다.

const s1 = Symbol.for('mySymbol')
Symbol.keyFor(s1) // mySymbol

const s2 = Symbol('foo') // Symbol 함수를 호출해 생성한 심벌 값은 전역 심벌 레지스트리에 등록되어 관리되지 않는다.
Symbol.keyFor(s2) // undefined

33.3. 심벌과 상수

변경/중복될 가능성이 있는 무의미한 상수 대신 중복될 가능성이 없는 유일무이한 심벌 값을 이용해 관리할 수 있다.

33.4. 심벌과 프로퍼티 키

심벌 값은 객체의 프로퍼티 키로 사용할 수 있다. 심벌 값에 대괄호를 사용하여 키를 생성하거나 프로퍼티에 접근할 수 있다.

const obj = {
  [Symbol.for('mySymbol')]: 1,
}

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

33.5. 심벌과 프로퍼티 은닉

심벌 값이 프로퍼티 키인 프로퍼티는 for ... in문이나 Object.keys, Object.getOwnPropertyNames 메서드로 찾을 수 없어 프로퍼티를 은닉할 수 있다.
그러나 ES6에서 도입된 Object.getOwnPropertySymbols를 사용하면 심벌 값이 프로퍼티 키인 프로퍼티를 찾을 수 있다.

33.6. 심벌과 표준 빌트인 객체 확장

표준 빌트인 객체에 사용자 정의 메서드를 추가하여 확장하는 것은 권장하지 않는다. 읽기 전용으로 사용하자.

직접 추가한 메서드가 미래에 추가될 메서드와 이름이 중복될 수 있다는 문제가 있어서 그렇지만, 심벌 값을 프로퍼티 키로 사용하면 충돌할 위험이 없어 안전하게 표준 빌트인 객체를 확장할 수 있다.

33.7. Well-known Symbol

자바스크립트가 기본 제공하는 심벌 값을 Well-known Symbol 이라 부른다.