Home 심볼.. 이 음흉한 녀석!
Post
Cancel

심볼.. 이 음흉한 녀석!

image

🌈 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 *전역 심볼만 가져올 수 있다.

🧐 그래서 어디다 씀?


  1. 주로 객체의 프로퍼티 키로 사용
  2. 무의미한 상수 대신에 중복될 가능성이 제로인 심볼을 사용
  3. 표준 빌트인 객체 확장시 사용 표준 빌트인 객체에 사용자 정의 메서드를 직접 추가하여 확장하는 것은 권장하는 방식이 아니다.
    그 이유는 개발자가 추가한 메서드와 미래에 표준 사양으로 추가될 메서드가 이름이 중복 될 수 있기 때문이다.

📌 심볼이 제공하는 것


  • JS가 기본적으로 제공하는 빌트인 심볼 값(Well-known Symbol) 이 있는데 심볼 함수의 프로퍼티에 할당되어 있다.
    • Array나 Object 자료형을 보면 기본으로 내장된 심볼들이 있다.
      1
      2
      3
      
      var array = [2, 3, 4];
      console.log(array[Symbol.iterator]);
      // 내장된 심볼이 뜸.
      
  • 이러한 빌트인 심볼 값은 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
This post is licensed under CC BY 4.0 by the author.

클로저는 프로게이머 아님?

이터러블, 이터레이터, 이터레이션 프로토콜.. 그래서 뭐가 뭔데?