Symbols
Symbols
ECMAScript 2015부터 symbol은 number, string처럼 기본(primitive) 데이터 타입이 됐어요. 객체의 프로퍼티 키로 쓰거나, 절대 충돌하지 않는 고유한 값을 만들고 싶을 때 유용합니다. 이 문서에서는 TypeScript에서 symbol을 다루는 방법을 소개할게요.
출처: TypeScript 핸드북
symbol 값은 Symbol 생성자를 호출해 만들 수 있어요.
let sym1 = Symbol();
let sym2 = Symbol("key"); // optional string key
Symbol은 불변이고 고유합니다. 같은 문자열 키로 두 개를 만들어도 서로 다릅니다.
let sym2 = Symbol("key");
let sym3 = Symbol("key");
sym2 === sym3; // false, symbols are unique
문자열처럼 symbol도 객체 프로퍼티의 키로 쓸 수 있어요.
const sym = Symbol();
let obj = {
[sym]: "value",
};
console.log(obj[sym]); // "value"
Symbol은 계산된 프로퍼티(computed property) 선언과 결합해 객체 프로퍼티나 클래스 멤버를 선언할 때도 쓸 수 있습니다.
const getClassNameSymbol = Symbol();
class C {
[getClassNameSymbol]() {
return "C";
}
}
let c = new C();
let className = c[getClassNameSymbol](); // "C"
unique symbol
Symbol을 고유한 리터럴처럼 취급할 수 있도록, 특별한 타입 unique symbol이 준비되어 있어요. unique symbol은 symbol의 하위 타입이며, Symbol()이나 Symbol.for() 호출, 또는 명시적 타입 주석으로만 만들어집니다. 이 타입은 const 선언과 readonly static 프로퍼티에만 허용되고, 특정 unique symbol을 가리키려면 typeof 연산자를 써야 해요. unique symbol에 대한 각 참조는 특정 선언에 묶인 완전히 고유한 정체성을 뜻합니다.
// @errors: 1332
declare const sym1: unique symbol;
// sym2 can only be a constant reference.
let sym2: unique symbol = Symbol();
// Works - refers to a unique symbol, but its identity is tied to 'sym1'.
let sym3: typeof sym1 = sym1;
// Also works.
class C {
static readonly StaticSymbol: unique symbol = Symbol();
}
각 unique symbol은 완전히 분리된 정체성을 가지므로, 서로 다른 두 unique symbol 타입은 서로 할당되거나 비교될 수 없어요.
// @errors: 2367
const sym2 = Symbol();
const sym3 = Symbol();
if (sym2 === sym3) {
// ...
}
잘 알려진 Symbol (Well-known Symbols)
사용자가 정의한 symbol 외에도, 언어가 내부 동작을 나타내기 위해 쓰는 내장 symbol이 있어요. 이들을 잘 알려진 symbol이라고 부릅니다. 각각이 어떤 동작에 관여하는지 차례대로 볼게요.
Symbol.asyncIterator
객체에 대한 비동기 이터레이터를 반환하는 메서드예요. for await..of 루프에서 쓸 수 있게 해줍니다.
Symbol.hasInstance
생성자 객체가 특정 객체를 자신의 인스턴스로 인식하는지 판단하는 메서드예요. instanceof 연산자의 의미에 따라 호출됩니다.
Symbol.isConcatSpreadable
객체를 Array.prototype.concat에서 배열 요소로 펼쳐야 하는지 알려주는 Boolean 값입니다.
Symbol.iterator
객체의 기본 이터레이터를 반환하는 메서드예요. for-of 문의 의미에 따라 호출됩니다.
Symbol.match
정규 표현식을 문자열에 매칭시키는 정규식 메서드예요. String.prototype.match 메서드가 호출합니다.
Symbol.replace
문자열에서 매칭된 부분 문자열을 교체하는 정규식 메서드예요. String.prototype.replace 메서드가 호출합니다.
Symbol.search
문자열 안에서 정규 표현식과 매칭되는 인덱스를 반환하는 정규식 메서드입니다. String.prototype.search 메서드가 호출합니다.
Symbol.species
파생 객체를 만들 때 쓰는 생성자 함수 값을 가진 프로퍼티예요.
Symbol.split
정규 표현식과 매칭되는 인덱스에서 문자열을 나누는 정규식 메서드입니다. String.prototype.split 메서드가 호출합니다.
Symbol.toPrimitive
객체를 대응하는 기본 값으로 변환하는 메서드예요. ToPrimitive 추상 연산이 호출합니다.
Symbol.toStringTag
객체의 기본 문자열 설명을 만들 때 쓰는 String 값입니다. 내장 메서드 Object.prototype.toString이 호출합니다.
Symbol.unscopables
자기 자신의 프로퍼티 이름들이 관련 객체의 with 환경 바인딩에서 제외되는 프로퍼티 이름인 Object예요.