JavaScript의 Symbol 데이터 타입

Symbol 데이터 타입

매주 진행하는 스터디에서 JavaScript의 7번째 데이터 타입인 Symbol을 다루었는데, 토의 시간에 이건 실무에서도 쓸 일이 거의 없을 것이고 앞으로 볼 일이 없을거라고 해서 까먹을까봐 Symbol에 대한 공부내용을 남겨둔다.

Symbol이란?

  • ES6에서 도입된 7번째 데이터 타입으로, 변경이 불가능한 원시 타입의 값이다.
    • 그 전까지 자바스크립트에는 String, Number, Boolean, undefined, null이라는 원시 타입의 값과 객체 타입의 값, 이렇게 여섯개의 유형이 존재했다.
  • 다른 값과 중복되지 않는 유일무이한 값이다.
  • 이름의 충돌 위험이 없는 유일한 프로퍼티 키를 만들기 위해 사용한다.
    • 프로퍼티 키로 사용할 수 있는 값은 문자열 또는 심벌 밖에 없다.

표준 빌트인 객체의 확장을 위한 심벌 타입 값의 사용

  • Symbol은 표준 빌트인 객체를 확장, 즉 사용자 정의 메서드를 직접 추가할 경우 전무후무 유일무이한 프로퍼티 키가 와야만 하기 때문에 고안되었다고 볼 수 있다.
  • 예컨대 내가 자바스크립트 라이브러리를 만들면서, 배열 안의 중복되는 요소를 제거하는 Array.prototype.unique라는 메서드를 내맘대로 만든다고 하자.
  • 이후 unique라는 식별자로 Array의 프로토타입에 메서드가 추가된 ECMAScript 사양이 등장할 수 있다.
  • 그 메서드가 내가 만든 메서드와 정확히 일치하는 반환값을 내는 게 아니라면 그 동안 내 라이브러리를 통해 만들어진 모든 프로그램에는 문제가 생긴다.
    • 내가 만든 라이브러리가 전세계에서 절찬리에 잘 사용되고 있다면(그 정도라면 ECMAScript가 알아서 다른 이름으로 메서드를 짓겠지만) 문제의 규모는 어마무시할 것이다.
  • 즉, 개발자가 임의로 표준 빌트인 객체의 프로토타입에 프로퍼티를 추가할 경우 전에도 앞으로도 없을 식별자를 사용해야만 한다. 그러나 어떤 문자열도 이 리스크로부터 100% 자유로울 순 없다.
  • 이 때문에 ES6부터는 Symbol이라는 값의 타입을 제시하며 Symbol을 객체의 프로퍼티 키로 사용할 수 있는 권한을 준 것이다.
  • 그러나 이러한 경우는 극히 드물며 프로토타입에 사용자 정의 메서드를 추가하는 것 자체가 안티패턴이기 때문에, 내가 앞으로 공부하거나 일하면서 Symbol을 만날 확률은 0에 수렴한다.

그 외의 사용

  • 상수 정의를 위한 사용
    • 특별한 의미가 없는 값을 프로퍼티 값으로 가진 상수를 정의해야 할 때, 랜덤한 문자열이나 숫자를 넣을 수도 있지만 중복될 가능성이 없는 유일무이한 심벌 값을 사용할 수 있다.
    • 그러나 이것도 굳이 그렇게 할 수 있다는 것이지 잘 쓰이진 않는다.
  • 프로퍼티 은닉
    • 심벌 값을 프로퍼티 키로 사용하여 생성한 경우 for ... in문이나 Object.keys, Object.getOwnPropertyNames 메서드를 통해 찾을 수가 없다. 그래서 외부에 노출할 필요 없는 프로퍼티를 은닉할 수 있다.
    • 그러나 이것도 굳이 그렇게 할 수 있다는 것 뿐이며, 찾으려면 Object.getOwnPropertySymbol로 찾을 순 있다.

Well-known Symbol

  • 자바스크립트가 기본으로 제공하는 빌트인 심벌 값이 있는데, 이를 Well-known Symbol이라고 ECMAScript는 명명한다. 이는 자바스크립트 엔진의 내부 알고리즘에 사용된다고 한다.
  • 대표적인 것이 이터레이션 프로토콜에서 이터러블 객체인지의 여부를 판단하는 Symbol.iterator 메서드이다.
    • 이 메서드를 호출하면 이터레이터를 반환하며, 개발자가 일반 객체를 이터러블로 동작하게끔 하고 싶을 때 이 메서드를 객체에 추가하고 이터레이터를 반환하게끔 구현하면 된다.

결론

  • Symbol은 중복되지 않는다는 속성으로 표준 빌트인 객체에 메서드를 추가할 때 하위호환성을 확보할 수 있다는 것이 가장 큰 효용이지만 다른 방법으로도 사용할 순 있다.
  • 하지만 우리가 그걸 사용할 일은 없을 것이며, 이터레이션 프로토콜과 이터러블 객체 속에서 만나보는 것이 전부일 것이다.

느낀 점

  • 잊어버릴 게 아까워 올린 글이지만 그래도 알아두어 나쁠 건 없으니까… 뿌듯하다.

참고자료