* 아래 내용은 이웅모 저자님의 모던 자바스크립트 Deep Dive 책(위키북스)을 정리한 내용입니다.
저작권에 문제가 된다면 삭제하도록 하겠습니다.
33.1 Symbol 이란?
ES6에서 도입된 7번째 데이터 타입으로 변경 불가능한 원시 타입의 값이다.
Symbol값은 다른 값과 중복되지 않는 유일무이한 값이다.
33.2 Symbol 값의 생성
33.2.1 Symbol 함수
Symbol값은 Symbol 함수를 통해서만 생성 가능하다. Symbol값을 생성할 때 문자열을 인수로 전달할 수 있는데, 이 문자열은 Symbol값에 대한 설명으로 디버깅 용도로만 사용된다.
// Symbol 함수를 호출하여 유일무이한 심벌 값을 생성한다.
const mySymbol = Symbol('my');
console.log(typeof mySymbol); // symbol
// 심벌 값은 외부로 노출되지 않아 확인할 수 없다.
console.log(mySymbol); // Symbol()
Symbol값은 암묵적으로 문자열이나 숫자 타입으로는 변환되지 않지만, 불리언 타입으로는 변환된다.
const mySymbol = Symbol();
// 불리언 타입으로는 암묵적으로 타입 변환된다.
console.log(!!mySymbol); // true
// if 문 등에서 존재 확인을 위해 사용할 수 있다.
if (mySymbol) console.log('mySymbol is not empty.');
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 메서드를 사용하면 전역 심벌 레지스트리에서 저장된 심벌 값의 키를 추출할 수 있다.
// 전역 심벌 레지스트리에 mySymbol이라는 키로 저장된 심벌 값이 없으면 새로운 심벌 값을 생성
const s1 = Symbol.for('mySymbol');
// 전역 심벌 레지스트리에 저장된 심벌 값의 키를 추출
Symbol.keyFor(s1); // -> mySymbol
// Symbol 함수를 호출하여 생성한 심벌 값은 전역 심벌 레지스트리에 등록되어 관리되지 않는다.
const s2 = Symbol('foo');
// 전역 심벌 레지스트리에 저장된 심벌 값의 키를 추출
Symbol.keyFor(s2); // -> undefined
33.3 Symbol과 상수
값에는 특별한 의미가 없고 상수 이름 자체에 의미가 있는 경우 Symbol값을 사용할 수 있다.
// 위, 아래, 왼쪽, 오른쪽을 나타내는 상수를 정의한다.
// 중복될 가능성이 없는 심벌 값으로 상수 값을 생성한다.
const Direction = {
UP: Symbol('up'),
DOWN: Symbol('down'),
LEFT: Symbol('left'),
RIGHT: Symbol('right')
};
const myDirection = Direction.UP;
if (myDirection === Direction.UP) {
console.log('You are going UP.');
}
33.4 Symbol과 프로퍼티 키
객체의 프로퍼티 키로 Symbol값을 사용할 수 있다. Symbol값은 유일무이하므로 Symbol값으로 프로퍼티 키를 만들면 다른 프로퍼티 키와 절대 충돌하지 않는다.
const obj = {
// 심벌 값으로 프로퍼티 키를 생성
[Symbol.for('mySymbol')]: 1
};
obj[Symbol.for('mySymbol')]; // -> 1
33.5 Symbol과 프로퍼티 은닉
Symbol값으로 프로퍼티 키를 만들면 for ... in 문이나 Object.keys, Object.getOwnPropertyNames 메서드로 찾을 수 없다.
하지만 Object.getOwnPropertySymbols 메서드로는 찾을 수 있다.
const obj = {
// 심벌 값으로 프로퍼티 키를 생성
[Symbol('mySymbol')]: 1
};
for (const key in obj) {
console.log(key); // 아무것도 출력되지 않는다.
}
console.log(Object.keys(obj)); // []
console.log(Object.getOwnPropertyNames(obj)); // []
// getOwnPropertySymbols 메서드는 인수로 전달한 객체의 심벌 프로퍼티 키를 배열로 반환한다.
console.log(Object.getOwnPropertySymbols(obj)); // [Symbol(mySymbol)]
// getOwnPropertySymbols 메서드로 심벌 값도 찾을 수 있다.
const symbolKey1 = Object.getOwnPropertySymbols(obj)[0];
console.log(obj[symbolKey1]); // 1
33.6 Symbol과 표준 빌트인 객체 확장
개발자가 직접 추가한 메서드와 미래에 표준 사양으로 추가될 메서드의 이름이 중복될 수 있기 때문에 일반적으로 표준 빌트인 객체에 사용자 정의 메서드를 직접 추가하는 것은 권장하지 않는다.
하지만 중복될 가능성이 없는 Symbol값으로 프로퍼티 키를 생성하여 표준 빌트인 객체를 확장하면 미래에 어떤 메서드가 추가되더라도 안전하게 표준 빌트인 객체를 확장할 수 있다.
33.7 Well-known Symbol
Javascript가 기본 제공하는 빌트인 Symbol값을 ECMAScript 사양에서는 Well-known Symbol이라고 부른다. Well-known Symbol은 JS 엔진 내부 알고리즘에 사용된다.
빌트인 이터러블은 Well-known Symbol인 Symbol.iterator를 키로 갖는 메서드를 가지며, Symbol.iterator 메서드를 호출하면 이터레이터를 반환하도록 ECMAScript 사양에 규정되어 있다.
Reference
- 이웅모 , 모던 자바스크립트 Deep Dive , 위키북스 , 2020
'개인공부 > 모던 자바스크립트 Deep Dive' 카테고리의 다른 글
35장 스프레드 문법 (1) | 2023.01.16 |
---|---|
34장 이터러블(iterable) (0) | 2023.01.16 |
26장 ES6 함수의 추가 기능 (0) | 2023.01.15 |
24장 클로저 (0) | 2023.01.10 |
22장 this (0) | 2023.01.09 |
댓글