Search

7번째 데이터 타입 Symbol

33.1 심벌이란?

es6에서 추가된 7번째 데이터 타입으로 변경 불가능한 원시 타입의 값입니다.

33.2 심벌 값의 생성

33.2.1 Symbol 함수

심벌 값은 Symbol 함수를 호출하여 생성해야 하며, 다른 값과 절대 중복되지 않는 유일무이한 값입니다.
const mySymbol = Symbol(); console.log(typeof mySymbol); // symbol
JavaScript
복사
언뜻 보면 생성자 함수로 객체를 생성하는 것 같지만 new 연산자와 함께 호출하지 않습니다. 만약 new 연산자와 함께 생성자 함수 또는 클래스를 호출하면 객체가 생성되지만 심벌 값은 변경 불가능한 원시 값입니다.
new Symbol(); // TypeError: Symbol is not a constructor
JavaScript
복사
심벌 값은 설명이 같더라도 유일무일한 심벌 값을 생성합니다.
const s1 = Symbol('12'); const s2 = Symbol('12'); console.log(s1 === s2); // false
JavaScript
복사
심벌 값도 문자열, 숫자 등과 같이 객체처럼 접근하면 암묵적으로 래퍼 객체를 생성합니다.
const s1 = Symbol('sym'); console.log(s1.description); // sym console.log(s1.toString()); // Symbol(sym)
JavaScript
복사
심벌 값은 암묵적으로 문자열이나 숫자 타입으로 변환되지 않습니다.
단 불리언 타입으로는 암묵적으로 변환됩니다.
const mySymbol = Symbol(); console.log(!!mySymbol); // true if(mySymbol) console.log('empty'); // empty
JavaScript
복사

33.2.2 Symbol.for / Symbol.keyFor 메서드

Symbol.for 메서드는 인수로 전달받은 문자열을 키로 사용하여 키와 심벌 갑스이 쌍들이 저장되어 있는 전역 심벌 레지스트리에서 해당 키와 일치하는 심벌 값을 검색합니다.
검색에 성공 시 새로운 심벌 값을 생성하지 않고, 검색된 심벌값을 반환합니다.
검색에 실패 시 새로운 심벌 값을 생성합니다.
Symbol 함수는 호출될 때마다 유일무이한 심벌 값을 생성하는데, 이때 엔진이 관리하는 값 저장소인 전역 심벌 레지스트리에서 심벌 값을 검색할 수 있는 키를 지정할 수 없으므로, 전역 심벌 레지스트리에 등록되어 관리되지 않습니다.
Symbol.keyFor 메서드를 사용하면 전역 심벌 레지스트리에 저장된 심벌 값의 키를 추출할 수 있습니다.
const s1 = Symbol.for('mys'); Symbol.keyFor(s1); // mys const s2 = Symbol('mys2'); Symbol.keyfor(s2); // undefined
JavaScript
복사

33.3 심벌과 상수

심벌을 통해 상수를 심벌처럼 사용할 수 있습니다.
const Direction = { UP: Symbol('up'), DOWN: Symbol('down'), LEFT: Symbol('left'), RIGHT: Symbol('right'), }; const myDirection = Direction.UP if(myDirection === Direction.UP) { console.log('find'); }
JavaScript
복사
JS에서 enum을 흉내낼 경우 Symbol과 Object.freeze를 사용합니다.

33.4 심벌과 프로퍼티 키

빈 문자열을 포함한 모든 문자열 또는 심벌 값으로 만들 수 있으며, 동적으로 생성 할 수도 있습니다.
const obj = { [Symbol.for('sym')]: 1 }
JavaScript
복사
심벌 값은 유일무이한 값이므로 심벌 값으로 프로퍼티 키를 만들면 다른 프로퍼티 키와 절대 충돌하지 않는 장점이 있습니다.

33.5 심벌과 프로퍼티 은닉

심벌값으로 생성한 프로퍼티 키는 for…in이나 Object.keys로 찾을 수 없습니다. 하지만 Object.getOwnPropertySymbols 메서드를 사용하면 심벌 값을 프로퍼티 키로 사용하여 심성한 프로퍼티를 찾을 수 있습니다.

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

이를 권장하진 않고, 읽기 전용으로 사용하는 것이 좋습니다.
// 표준 빌트인 객체를 확장하는 것은 권장하지 않습니다. Array.prototype.sum = function(){ return this.reduce((acc, cur) => acc + cur, 0); }; [1, 2].sum(); // 3
JavaScript
복사
이유는 개발자가 직접 추가한 메서드와 미래에 표준사용으로 추가될 메서드의 이름이 중복될 수 있기 때문입니다.

33.7 Well-known Symbol

자바스크립트가 기본 제공하는 빌트인 신벌 값을 ECMAScript 사양에는 Well-known Symbol이라고 부릅니다. 이것은 내부 알고리즘에 사용됩니다.
만약 빌트인 이터러블이 아닌 일반 객체를 이터러블처럼 동작하도록 구현하고 싶다면 이터레이선 프로토콜을 따르게 되는데, Well-known Symbol인 Symbol.iterator를 키로 갖는 메서드를 객체에 추가하고 이터레이터를 반환하도록 구현하면 그 객체는 이터러블이 됩니다.
const interable = { [Symbol.iterator](){ let cur = 1; const max = 5; return { next() { return { value: cur++, done: cur > max + 1 }; } } } }; for(const num of iterable){ console.log(num); // 1 2 3 4 5 }
JavaScript
복사
이때 이터레이션 프로토콜을 준수하기 위해 일반 객체에 추가해야하는 메서드키 Symbol.iterator는 기조 ㄴ프로퍼티 키 또는 미래에 추가될 프로퍼티 키와 절대로 중복되지 않을 것 입니다. 이처럼 심벌은 중복되지 않는 상수 값을 생성하는 것은 물론 기존에 작성된 코드에 영향을 주지 않고 새로운 프로퍼티를 추가하기 위해 도입되었습니다.