Javascript Symbol(심볼)

NSH·2022년 6월 1일
0

1. 심볼형

자바스크립트의 심볼(Symbol)은 ES6에서 새롭게 추가된 변경 불가능한 원시 타입의 값이다.
객체의 프로퍼티 키로는 문자형과 심볼형만 허용한다. 객체의 프로퍼티 키로 심볼값을 사용하면 어떤 장점이 있는지 알아보자.

2. 심볼(Symbol)

Symbol은 유일한 식별자를 만들고 싶을 때 사용한다. SymbolSymbol() 함수로 생성할 수 있다. 이때 생성된 Symbol 값은 객체가 아닌 변경 불가능한 원시 타입이다.

let id = Symbol();
console.log(id); 	    // Symbol()
console.log(typeof id); // Symbol

Symbol을 만들 때 Symbol의 설명을 붙일 수 있다. Symbol의 설명은 디버깅 시 아주 유용하게 사용된다.

let id = Symbol('id symbol description');
console.log(id); // Symbol(id symbol description)

Symbol은 유일한 식별자이므로 같은 설명을 가진 Symbol 두 개를 만들고 비교해도 동일 연산자 비교 시 false가 반환된다.

let id1 = Symbol('id1 symbol description');
let id2 = Symbol('id2 symbol description');
console.log(id1 == id2); // false

3. 심볼(Symbol)의 사용

Symbol값은 객체의 프로퍼티 키로 사용할 수 있다. Symbol값은 유일한 값으로 Symbol을 키로 갖는 프로퍼티는 다른 어떤 프로퍼티와도 충돌하지 않는다.

const obj = {};

const mySymbol = Symbol('mySymbol');
obj[mySymbol] = 123;

console.log(obj) 			// { [Symbol(mySymbol)]: 123 }
console.log(obj[mySymbol]); // 123

4. 심볼(Symbol) 객체

Symbol()Symbol 값을 생성할 수 있다. 이것은 Symbol이 함수 객체라는 것을 의미한다.

Symbol 함수 객체는 프로퍼티와 메소드를 가지고 있다. Symbol 객체의 프로퍼티 중 length와 prototype을 제외한 프로퍼티를 Well-Known Symbol 이라 부른다.

4.1 Symbol.iterator

Well-Known Symbol은 자바스크립트 엔진에 상수로 존재하며 Well-known-Symbol을 참조하여 일정한 처리를 한다.

예를 들면, 어떤 객체가 Symbol.iterator를 프로퍼티 키로 사용한 메소드를 가지고 있으면, 자바스크립트 엔진은 이 객체가 이터레이션 프로토콜을 따르는 것으로 간주하고 이터레이터로 동작하도록 한다.

Symbol.iterator를 프로퍼티 키로 사용해여 메소드를 구현하고 있는 객체는 아래와 같다. 아래의 객체들은 이터레이션 프로토콜을 준수하고 있으며 이터레이터를 반환한다.

Array.prototype[Symbol.iterator]; 			// Array
String.prototype[Symbol.iterator];			// String
Map.prototype[Symbol.iterator] 	  			// Map
Set.prototype[Symbol.iterator] 	  			// Set
NodeList.prototype[Symbol.iterator]			// DOM data structures
HTMLCollection.prototype[Symbol.iterator]	// DOM data structures

4.2 이터러블

이터러블은 Symbol.iterator를 프로퍼티 키로 가지고 있는 객체이다. 배열에는 Array.prototype[Symbol.iterator] 메소드가 구현되어 있다.

const iterable = ['a', 'b', 'c'];

4.3 이터레이터

Symbol.iterator를 프로퍼티 키로 가지고 있는 메소드는 이터레이터를 반환한다. 이터레이터는 순회 가능한 자료 구조인 이터러블의 요소를 탐색하기 위한 포인터로 value, done 프로퍼티를 갖는 객체를 반환하는 next() 함수를 메소드로 갖는 객체이다.

const itertator = iterable[Symbol.iterator];
console.log(iterator.next()); // { value: 'a', done: false }
console.log(iterator.next()); // { value: 'b', done: false }
console.log(iterator.next()); // { value: 'c', done: false }
console.log(iterator.next()); // { value: undefined, done: true }

5. Symbol.for

Symbol.for 메소드는 인자로 전달받은 문자열을 키로 사용하여 Symbol 값들이 저장되어 있는 전역 Symbol 레지스트리에 해당 키와 일치하는 저장된 Symbol 값을 검색한다.

검색에 성공하면 Symbol 값을 반환하고, 실패하면 새로운 Symbol 값을 생성하여 해당 키로 전역 Symbol 레지스트리에 저장 후 Symbol 값을 반환한다.

// 전역 Symbol 레지스트리에 foo 라는 키로 저장된 Symbol이 없으면 새로운 Symbol 생성
const s1 = Symbol.for('foo');
// 전역 Symbol 레지스트리에 foo 라는 키로 저장된 Symbol이 있으면 해당 Symbol 반환
const s2 = Symbol.for('foo');

Symbol 함수는 매번 다른 Symbol 값을 생성하지만, Symbol.for 메소드는 하나의 Symbol을 생성하여 여러 모듈이 키를 통해 같은 Symbol을 공유할 수 있다.

Symbol.for 메소드를 통해 생성된 Symbol 값은 반드시 키를 가진다. Symbol 함수를 통해 생성된 값은 키가 없다.

6. 결론

Symbol 함수는 유일한 식별자인 Symbol 값을 반환하고 Symbol 값은 객체의 프로퍼티 값으로 사용해서 어떤 프로퍼티와도 충돌하지 않게 사용할 수 있다.

Symbol.iterator 메소드를 가지고 있는 객체를 이터러블 이라고 부르며 Symbol.iterator 메소드는 이터레이터를 반환한다. 이터레이터는 순회 가능한 자료 구조인 이터러블 요소를 탐색하기 위해 value, done 프로퍼티를 반환하는 next() 함수를 가진다.

profile
잘 하고 싶다.

0개의 댓글