이 글은 '이웅모'님의 '모던 자바스크립트 Deep Dive' 책을 통해 공부한 내용을 정리한 글입니다. 저작권 보호를 위해 책의 내용은 요약되었습니다.
ES6에서 도입된 7번째 데이터 타입으로 변경 불가능한 원시 타입의 값이다. 즉, 다른 값과 중복되지 않는 유일무이한 값이다. 주로 유일한 프로퍼티 키를 만들기 위해 사용되곤 한다.
래퍼 객체를 생성하는 생성자 함수와 달리 new
연산자를 사용하지 않는다.
const symbol = Symbol();
const sym1 = Symbol('sem');
const sym2 = Symbol('sem');
console.log(sym1, sym2, sym1 === sym2); // Symbol(sem) Symbol(sem) false
Symbol
함수에 문자열을 전달할 수 있다. 이는 심볼 생성에 어떠한 영향을 주지 않는다. 단지 생성된 심볼에 대한 설명으로써 주로 디버깅 용도로 사용된다.
심볼 객체는 프로퍼티와 메서드를 소유하고 있는데, 프로퍼티 중 length
와 prototype
을 제외한 나머지 프로퍼티를 Well-Known Symbol
이라 부른다.
Well-known Symbol
은 자바스크립트 엔진에 상수로 존재하며, 자바스크립트 엔진은 이를 참조하여 일정한 처리를 수행한다. 만약 어떠한 객체가 Symbol.iterator
프로퍼티를 key
로 사용한 메서드를 가지고 있다면 자바스크립트 엔진은 이 객체가 이터레이션 프로토콜을 따르는 것으로 간주하고 이터레이터로 동작하도록 한다.
Symbol.iterator
를 프로퍼티 key
로 사용하여 메서드를 구현하는 빌트인 객체는 다음과 같다.
예를 들어보면 다음과 같다.
const arr = [1,2,3,4];
const iterator = arr[Symbol.iterator](); // Array Iterator
console.log(iterator.next()); // {value: 1, done: false}
console.log(iterator.next()); // {value: 2, done: false}
console.log(iterator.next()); // {value: 3, done: false}
console.log(iterator.next()); // {value: 4, done: false}
console.log(iterator.next()); // {value: undefined, done: true}
인자로 전달받은 문자열을 키로 사용하여 Symbol
값들이 저장되어 있는 전역 심볼 레지스트리에서 해당 키와 일치하는 Symbol
을 검색한다. 만약 검색에 실패하면 인자를 키로 사용하는 새로운 심볼을 반환한다.
const sym1 = Symbol.for('sem'); // sem을 키로 가지는 새로운 심볼 생성
const sym2 = Symbol.for('sem'); // sem을 키로 가지는 심볼 반환
console.log(sym1 === sym2); // true
console.log(Symbol.keyFor(sym1), Symbol.keyFor(sym2)) // sem sem
Symbol
함수는 매번 다른 심볼 값을 생성하지만, Symbol.for
메서드는 하나의 심볼로 여러 모듈이 키를 통해 같은 심볼을 공유할 수 있도록 한다.