ES6 - Symbol

lingodingo·2020년 7월 1일
1

DailyStudy

목록 보기
2/3

@krisoller from unsplash

개인적으로 심볼을 쓰는 개발자를 내 주변에서는 한 번도 보지 못했다. 또한 자신이 오픈 소스의 커미터가 아닌 이상 이걸 실사용해본 개발자는 많지 않을 것이라 생각한다. 그래도 뭐 알아두면 어딘가에 쓸모는 있을테니 정리해본다.


JS는 타입을 지정하지 않아도 알아서 잘 동작한다. 하지만 이는 표면적으로 보여지지 않을 뿐, 내부에서는 하나하나 타입을 지정해주고 변환하여 우리에게 값을 준다. 타입이 없다면 해당 변수가 메모리에 얼만큼 얼마나 할당 될지를 알 수가 없기 때문이다.

예를들어 const what = 10 + '20' 같은 구문을 만나게 되면 10은 number, '20'은 string으로 간주하여 10을 string으로 타입을 바꿔서 concat을 하게 된다. 변수 what은 '1020'의 string 타입을 갖게 된다.

따라서 JS도 타입을 쓰며, 심볼이 나오기 전 까진 6개의 타입을 갖고 있었다.

  • undefined
  • null
  • boolean
  • number
  • string
  • object

솔직하게 이 6개의 타입이면 모든 걸 잘 구현할 수 있을 것 같은데... 도대체 왜 새로운 타입인 Symbol을 추가하게 된 것일까?

예시를 보면서 이해하는 것이 가장 빠를 것이므로 하나의 스토리를 가정하고 이해해보자.


JS의 object는 이론상 무한개의 key를 가질 수 있다. 그렇다면 모든 자연수를 key로 갖고있는 변수가 있다고 가정해보자.

export const obj = {
  0: true,
  1: true,
  2: true,
  ...
  100: true,
  ...
  3915871234712359812741: true,
  ...
}

렛서팬더는 이 obj 변수를 라이브러리에서 가져왔다. 따라서 obj라는 존재만 알고 사용하고 있을 뿐, 그 안에 어떤 key가 있는지는 모른다. 별로 관심도 없다.
어느 날, 렛서팬더는 변수 obj에다가 자기가 좋아하는 숫자인 8739의 key를 넣고 싶어졌다. 그래서 넣었다. 안될게 뭔가? 혹시 이런 변태적인 수에 누가 값을 넣었을 것이라고 ㅎㅎ

obj[8739] = '💣';

하지만 아뿔싸, obj[8739]는 해당 라이브러리의 중요한 key였고, 그걸 덮어씀으로써 렛서팬더가 만들고 있는 프로그램은 해당 구문 하나때문에 '💣'하고 망가져버렸다.

세상엔 여러 사람이 있다보니까 이런 문제는 얼마든지 발생할 수 있다. 심지어 나는 지금 이 문제를 자연수범위에서 정의하고 있지만, 문자까지 확장해도 이런 케이스는 당연하게 생길 수 있다. 즉 key의 충돌을 고려해야 한다는 것이다.

key 충돌을 피하기 위해서 컴파일때 이름을 복잡하게 짓는다거나(TheBestOfNumberIs8739DontOverwriteThis), 런타임때 암호화해서 결정해 버린다면(3dhaj3...) 디버깅할때 미쳐버릴지도 모른다. 또한 키를 안전한 방법으로 추가한다 하더라도, for - in 구문이나, Object.keys가 고장난다면 어떻게 할 것인가?

이 방법때문에 Symbol이 나왔다고 한다.

const a = Symbol('8739');
obj[a] = '🤪'; // 절대 key 충돌나지 않을 것을 보장한다

심볼은 Object.keys에서 나타나지 않기 때문에 key를 iteration하는 코드가 있을 때 문제가 되지 않는다.

이런 특징으로 private 변수를 손쉽게 만들 수 있으며, 라이브러리 개발자는 다른 사용자가 key를 덮어쓰지 않을 까 하는 걱정을 덜 수 있게 되었다.

심볼에 더 자세한 내용을 알고 싶으면 ES6 - in depth symbol을 읽도록 하자.

profile
Frontend developer

0개의 댓글