ES6에서는 Symbol 이라는 원시형 데이터 타입이 새로이 도입되었다. 자바스크립트는 객체 프로퍼티 키로 오직 문자형과 심볼형만을 허용한다. 숫자형, 불린형은 불가능하다. 심볼은 유일한 식별자(unique identifier)를 만들고 싶을 때 사용한다.
// NOT A CONSTRUCTOR
// aSymbol은 새로운 심볼이 된다.
const aSymbol = Symbol();
// 심볼에 대한 설명을 붙일 수도 있다.
const aSymbol = Symbol('aSymbol');
alert(aSymbol.description) // aSymbol
심볼은 유일성이 보장되는 자료형이기 때문에 설명이 동일한 심볼을 여러개 만들어도 각 심볼값은 다르다. 심볼에 붙이는 설명은 어떤 것에도 영향을 주지 않는 이름표 역할만 할 뿐이다. (디버깅시 유용)
Symbol 비교
console.log(Number('2') === 2); // true
console.log({} === {}); // false 참조값이 다름.
console.log(undefined === undefined) // true
console.log(Symbol(`a`) === Symbol(`a`)); // false!!!
console.log(Symbol() === Symbol()); // false
동일 연산자로 비교 시 false
가 반환되는 것을 볼 수 있다.
객체와 같이 참조값을 비교하는 것일까?
What is the point? The point is... to avoid name collision.
const a = Symbol();
const b = Symbol();
console.log(a === b); // false
a
는 완전히 유일한, 복사 불가능한 변수가 된다. 참조값이 완전히 다른 무언가가 된다.
It can NEVER, ever be used again
심볼을 사용하여 숨겨진 프로퍼티를 만들 수 있다. 숨겨진 프로퍼티는 외부 코드에서 접근이 불가능하고 값도 덮어쓸 수 없다.
class Car {
constructor(color, make, model) {
this.color = color;
this.make = make;
this.model = model;
}
}
let myCar = new Car(`Red`, `Chevy`, `Tahoe`);
console.log(myCar); // Car {color: 'Red', make: 'Chevy', model: 'Tahoe'}
myCar.color = `blue`;
console.log(myCar); // Car {color: 'Blue', make: 'Chevy', model: 'Tahoe'}
Symbol
사용을 한다면const CARCOLOR = Symbol();
const CARMAKE = Symbol();
const CARMODEL = Symbol();
class Car {
constructor(color, make, model) {
this[CARCOLOR] = color;
this[CARMAKE] = make;
this[CARMODEL] = model;
}
}
let myCar = new Car(`Red`, `Chevy`, `Tahoe`);
// Symbol을 직접 호출하지 않으면 access 할 수 없다.
console.log(myCar); // Car {}
myCar.color = `blue`;
console.log(myCar); // Car {color: 'Blue'}
// 심볼을 키로 사용해 데이터에 접근이 가능하다.
console.log(myCar[CARMODEL]); // Tahoe
아래와 같이 수정하면 심볼로 만들어진 프로터티에 접근할 수 있다.
const CARCOLOR = Symbol();
const CARMAKE = Symbol();
const CARMODEL = Symbol();
class Car {
constructor(color, make, model) {
this[CARCOLOR] = color;
this[CARMAKE] = make;
this[CARMODEL] = model;
}
get color() {
return this[CARCOLOR];
}
set color(newColor) {
this[CARCOLOR] = newColor;
}
}
let myCar = new Car(`Red`, `Chevy`, `Tahoe`);
console.log(Symbol.for(`test`) === Symbol.for(`test`)); // true
private variable을 만들 수 있는 강력한 기능이라고 할 수 있다. 키가 심볼인 경우에는
for..in
의 대상이 되지 않아 의도치 않게 프로퍼티가 수정되는 것을 예방할 수 있다. 외부 스크립트나 라이브러리에서는 심볼 정보가 없기 때문에 프로퍼티에 직접 접근할 수도 없다.