🌈 Intro
최근 JS 스터디는 꾸준히 하고 있었지만 차마 글로 정리하지 못했다..😇
그동안 프로토타입, DOM 등을 다뤘었는데 프로토타입은 너무 방대하기도 했고, 당시 코테가 몰려 있어서 시간이 없었다.
DOM은 뭔가 장황한거에 비해 내용이 별로 없어서 작성하지 않았는데 다 핑계라는 생각이 들었다.
그래서 조금의 반성의 시간을 갖고 이번 심볼로 새출발한다!
🌲 알고 가면 좋은 배경 지식
자바스크립트에는 원시 타입과 참조 타입이 있다.
이번에 다룰 심볼은 원시타입이다. 원시타입은 값 자체가 메모리에 저장되고, 참조 타입은 값이 저장된 메모리 주소를 참조한다. ES6 이전의 원시 타입 종류는 string, number, bigint, boolean, undefined
이었지만 ES6부터는 Symbol
이 추가되었다.
원시타입은 불변이다라는 사실만 기억하고 넘어가보자.
❔ Symbol..?
mdn 문서에 따르면 "심볼" 데이터 형식은 값으로 익명의 객체 속성(object property)을 만들 수 있는 특성을 가진 원시 데이터 형식(primitive data type)입니다.
라고 설명하고 있다.
심볼은 원시 타입이기에 주로 이름의 충돌 위험이 없는 유일무이한 객체의 프로퍼티 키를 만들기 위해 사용된다. 즉, 심볼은 객체 자료형의 아~주 비밀스러운 키값이라고 할 수 있다.
심지어 이 은밀한 녀석은 반복문으로 순회할 때 무시되어 노출되지 않는다.
💪🏻 그래서 어떻게 씀?
1. 생성 방법
- 심볼은 원시타입이기에 다른 값과 절대 중복되지 않는 유일 무이한 값이다.
- 다른 원시값과 다르게 함수 호출로 생성이 가능하다.(리터럴 표기법이 불가능하다)
- 기본적으로 생성은
Symbol
메소드와Symbol.for
메소드를 통해 생성할 수 있다.
1
2
3
4
5
const symbol = Symbol("symbol"); // 기본적인 심볼 생성
const symbol2 = Symbol("symbol"); // 심볼은 유일무이한 값이기에 symbol과 symbol2는 다른 값이다.
// Symbol.for 메소드를 통해 전역 심볼 레지스트리에 심볼을 등록할 수 있다.
// Symbol.for 메소드는 존재하면 존재하는 심볼을 반환하고, 존재하지 않으면 새로운 심볼을 생성한다.
const s1 = Symbol.for("foo");
2. 추출 방법
Symbol.for
,Symbol.keyFor
메소드를 통해 심볼을 추출할 수 있다.- 특이점이라면
Symbol.for
메소드는 존재하면 존재하는 심볼을 반환하고, 존재하지 않으면 새로운 심볼을 생성한다. Symbol.keyFor
메소드는 전역 심볼 레지스트리에 등록된 심볼을 가져올 수 있다.
1
2
3
4
5
6
// Symbol.for 메소드는 존재하면 존재하는 심볼을 반환하고, 존재하지 않으면 새로운 심볼을 생성한다.
const s1 = Symbol.for("foo");
// Symbol.keyFor 메소드를 통해 전역 심볼 레지스트리에 등록된 심볼을 가져올 수 있다.
connsole.log(Symbol.keyFor(s1)); // foo
console.log(Symbol.keyFor(symbol)); // undefined *전역 심볼만 가져올 수 있다.
🧐 그래서 어디다 씀?
- 주로 객체의 프로퍼티 키로 사용
- 무의미한 상수 대신에 중복될 가능성이 제로인 심볼을 사용
- 표준 빌트인 객체 확장시 사용 표준 빌트인 객체에 사용자 정의 메서드를 직접 추가하여 확장하는 것은 권장하는 방식이 아니다.
그 이유는 개발자가 추가한 메서드와 미래에 표준 사양으로 추가될 메서드가 이름이 중복 될 수 있기 때문이다.
📌 심볼이 제공하는 것
- JS가 기본적으로 제공하는 빌트인 심볼 값(Well-known Symbol) 이 있는데 심볼 함수의 프로퍼티에 할당되어 있다.
- Array나 Object 자료형을 보면 기본으로 내장된 심볼들이 있다.
1 2 3
var array = [2, 3, 4]; console.log(array[Symbol.iterator]); // 내장된 심볼이 뜸.
- Array나 Object 자료형을 보면 기본으로 내장된 심볼들이 있다.
- 이러한 빌트인 심볼 값은 JS 엔진 내부 알고리즘에 사용된다고 한다.
Array
,String
,Map
,Set
,TypedArray
,arguments
,NodeList
,HTMLCollection
과 같이for … of 문
으로 순회가능한 빌트인 이터러블은 Well-known Symbol인Symbol.iterator
를 키로 갖는 메서드를 가지고 있음1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
const iterable = { [Symbol.iterator]() { let cur = 1; const max = 10; return { next() { return { done: cur > max, value: cur++, }; }, }; }, }; for (const a of iterable) { console.log(a); // 1 2 3 4 5 6 7 8 9 10 }
코드는 이해하기 편하기 위해 객체를 이터러블하게 만들었지만, 실제로는
Array
,String
,Map
,Set
,TypedArray
,arguments
,NodeList
,HTMLCollection
등은 이미 이터러블하게 만들어져있다.이 부분은 다음 장인 이터러블에서 자세하게 다뤄봅시다!
📝 정리하자면..
심볼은 유일하고 변경 불가능한 데이터 타입으로, 다른 어떤 값과도 일치하지 않는 고유한 식별자를 만들기 위해 사용한다
주로 객체의 프로퍼티 키로 사용되는데 다른 속성 키와 구별되어 충돌을 방지 할 수 있고, 내부적으로는 숨겨진 값으로 처리되기 때문에 외부에서 접근할 수 없다.
이러한 심볼의 특징은 다른 값들과 정확하게 구분이 가능하게 하고, 의미를 명확하게 전달할 수 있다.
🙏🏻 Reference
- 모던 자바스트립트 Deep Dive