const mySymbol = Symbol();
console.log(typeof mySymbol); // symbol
// 심벌 값은 외부로 노출되지 않아 확인 X
console.log(mySymbol); // Symbol()
// Symbol 함수는 new 연산자와 함께 호출 X
new Symbol(); // TypeError: Symbol is not a constructor
const mySumbol1 = Symbol('mySymbol');
const mySumbol2 = Symbol('mySymbol');
console.log(mySumbol1 === mySumbol2); // false
const mySymbol = Symbol('mySymbol');
console.log(mySymbol.description); // mySymbol
console.log(mySymbol.toString()); // Symbol(mySymbol);
const mySymbol = Symbol();
// TypeError: Cannot convert a Symbol value to a string
console.log(mySymbol + '');
// TypeError: Cannot convert a Symbol value to a number
console.log(+mySymbol);
console.log(!!mySymbol); // true
// 전역 레지스트리에 mySymbol 키로 새로운 심벌 값 생성
const s1 = Symbol.for('mySymbol');
// 전역 레지스트리에 mySymbol 키로 저장된 심벌 값 반환
const s2 = Symbol.for('mySymbol');
console.log(s1 === s2); // true
Symbol 함수를 호출할 때마다 유일무이한 심벌 값을 생성함
반면에, Symbol.for 메서드를 사용하면 전역에서 중복되지 않는 유일무이한 심벌 값을 단 하나만 생성하여 전역 레지스트리를 통해 공유할 수 있음
Symbol.keyFor(Symbol)
// Symbol.for 메서드를 호출하여 새로 생성된 심벌 값은 전역 심벌 레지스트리에 등록 O
const s1 = Symbol.for('mySymbol');
Symbol.keyFor(s1); // mySymbol
const s2 = Symbol('foo');
// Symbol 함수를 호출하여 생성한 심벌 값은 전역 심벌 레지스트리에 등록 X
Symbol.keyFor(s2); // undefined
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');
}
객체의 프로퍼티 키
심벌 값을 프로퍼티 키로 사용할 때,
const obj = {
[Symbol.for('mySymbol')]: 1
};
obj[Symbol.for('mySymbol')]; // 1
const obj = {
[Symbol('mySymbol')]: 1
};
for (const key in obj) {
console.log(key); // 아무것도 출력되지 않음
}
console.log(Object.keys(obj)); // []
console.log(Object.getOwnPropertyNames(obj); // []
const obj = {
[Symbol('mySymbol')]: 1
};
// getOwnPropertySymbols 메서드는 주어진 객체의 모든 심벌 프로퍼티를 배열로 반환함
console.log(Object.getOwnPropertySymbols(obs)); // [Symbol(mySymbol)]
일반적으로 표준 빌트인 객체에 사용자 정의 메서드를 직접 추가하여 확장하는 것은 권장하지 않음
심벌 값으로 프로퍼티 키를 생성하여 표준 빌트인 객체를 안전하게 확장할 수 있음
Array.prototype[Symbol.for('sum')] = function () {
return this.reduce((acc, cur) => acc + cur, 0);
}
[1, 2][Symbol.for('sum')](); // 3
// 1 ~ 5 범위의 정수로 이루어진 이터러블
const iterable = {
// Symbol.iterator 메서드를 구현하여 이터러블 프로토콜을 준수
[Symbol.iterator]() {
let cur = 1;
const max = 5;
// Symbol.iterator 메서드는 next 메서드를 소유한 이터레이터를 반환함
return {
next() {
return {value: cur++, done: cur > max + 1}
}
};
}
};
for (const num of iterable) {
console.log(num); // 1 2 3 4 5
}