심벌이란?
•
ES6 이전 6개의 타입
◦
문자열
◦
숫자
◦
불리언
◦
undefined
◦
null
◦
객체
•
ES6에서 도입된 7번째 데이터 타입
•
변경 불가능한 원시 타입의 값
•
다른 값과 중복이 되지 않아서 이름의 충돌 위험이 없는 유일한 프로퍼티 키를 만들기 위해 사용!
•
프로퍼티 키로 사용할 수 있는 것 --> 빈 문자열을 포함하는 모든 문자열 또는 심벌 값
심벌 값의 생성
Symbol 함수
•
심벌 값
◦
Symbol 함수를 호출하여 생성
◦
외부로 노출되지 않아 확인할 수 없고, 다른 값과 절대 중복되지 않는 유일무이한 값
const mySymbol = Symbol();
console.log(typeof mySymbol); // symbol
// 심벌 값은 외부로 노출되지 않아 확인할 수 없다.
console.log(mySymbol) // Symbol()
TypeScript
복사
Symbol 함수는 new 연산자와 함께 호출 하면 TypeError가 발생
•
Symbol에 인수로 전달되는 문자열은 생성된 심벌 값에 대한 설명(Description)으로 디버깅 용으로만 사용되며, 심벌 값 생성에 어떠한 영향도 주지 않음
--> 심벌 값에 대한 설명이 같더라도 유일무이한 심벌 값
•
심벌 값 또한 암묵적으로 래퍼 객체를 생성하는데, description 프로퍼티와 Symbol.prototype의 toString 메서드 보유
•
암묵적으로 문자열이나 숫자 타입으로 변환되지는 않고, 불리언 타입으로는 변환
.for / .keyFor 메서드
•
Symbol.for 메서드는 인수로 전달받은 문자열을 키로 사용하여 키와 심벌 값의 쌍들이 저장되어 있는 전역 심벌 레지스트리에서 해당하는 키와 일치하는 심벌 값을 검색
◦
검색에 성공시 검색된 심벌 값을 반환
◦
검색에 실패시 새로운 심벌 값을 생성하여 Symbol.for 메서드의 인수로 전달된 키로 전역 심벌 레지스트리에 저장 후, 새로운 심벌 값을 반환
Symbol의 경우
- 호출 시마다 유일무이한 심벌 값을 생성 but 전역 심벌 레지스트리에서 관리X
- Symbol.for 메서드를 사용하면 전역에서 중복되지 않는 심벌 값을 단 하나만 생성하여 전역 심벌 레지스트리에서 공유 가능
•
Symbol.keyFor 메서드를 사용하면 전역 심벌 레지스트리에 저장된 심벌 값의 키를 추출 가능
const s1 = Symbol.for('mySymbol');
Symbol.keyFor(s1); // mySymbol
const s2 = Symbol('foo');
Symbol.keyFor(s2); // undefined
TypeScript
복사
심벌과 상수
•
객체 안에서 의미있는 상수를 정의하기 위해서는 다른 변수값과 중복되지 않는 심벌 값을 사용하여 정의하는 게 이상적
const Direction = {
UP: Symbol('up'),
DOWN: Symbol('down'),
LEFT: Symbol('left'),
RIGHT: Symbol('right')
};
TypeScript
복사
enum은 JS에서 지원하지는 않지만 객체의 변경을 방지하기 위해 객체를 동결하는 Object.freeze 메서드와 심벌값을 같이 사용하여 구현 가능
const Direction = Object.freeze({
UP: Symbol('up'),
DOWN: Symbol('down'),
LEFT: Symbol('left'),
RIGHT: Symbol('right')
});
TypeScript
복사
심벌과 프로퍼티 키
•
심벌 값으로 프로퍼티 키를 만들기 위해서는 대괄호 사용
•
접근시에도 대괄호 사용
const obj = {
[Symbol.for('mySymbol')]: 1
};
obj[Symbol.for('mySymbol')]; // -> 1
TypeScript
복사
심벌 값 = 유일무이한 값
심벌 값으로 프로퍼티 키를 만들면 다른 프로퍼티 키와 절대 충돌 X
심벌과 프로퍼티 은닉
•
심벌 값을 프로퍼티 키로 만든 프로퍼티는 for ... in 문이나 Object.keys, Object.getOwnPropertyNames 메서드로 찾을 수 없다.
•
그러나 ES6에서 도입된 Object.getOwnPropertySymbols 메서드 사용 시, 심벌 값을 프로퍼티 키로 사용하여 생성한 프로퍼티를 찾을 수 있다.
console.log(Object.getOwnPropertySymbols(obj));
TypeScript
복사
심벌과 표준 빌트인 객체 확장
•
표준 빌트인 객체에 사용자 정의 메서드를 직접 추가하는 것은 이름이 중복되어 덮어 씌어질 가능성이 있기 때문에 권장 X
•
이러한 경우 심벌 값으로 프로퍼티 키를 생성하여 이용
Array.prototype[Symbol.for('sum')] = function () {
return this.reduce((acc,cur) => acc + cur, 0);
};
[1,2][Symbol.for('sum')](); // -> 3
TypeScript
복사
Well-known Symbol
•
자바스크립트가 기본 제공하는 빌트인 심벌 값
•
Array, String, Map, Set과 같이 for ... of 문으로 순회 가능한 빌트인 이터러블은 Well-known Symbol인 Symbol.iterator를 키로 갖는 메서드를 갖고, 이를 호출 하면 이터레이터를 반환
•
빌트인 이터러블 --> 이터레이션 프로토콜 준수
•
일반 객체에 이터러블처럼 동작하도록 구현하는 방법
const iterable = {
// 이 메서드를 구현하여 이터러블 프로토콜 준수
[Symbol.iterator]() {
let cur = 1;
const max = 5;
return {
// Symbol.iterator 메서드는 next 메서드를 소유한 이터레이터를 반환
next() {
return { value: cur++, done: cur > max + 1};
}
};
}
};
for (const num of iterable) {
console.log(num); // 1 2 3 4 5
}
TypeScript
복사