-
묵혔다 꺼낸 JS - Symbol 탐구JS 2021. 9. 12. 00:38
Symbol에 대해
자바스크립트에서 심볼 객체(Symbol Object)는 Primitive(=원시적의) 데이터 형으로 객체의 Private 접근성을 가진 멤버를 생성하기 위해서 태어났다고 한다.
심볼 생성
심볼을 생성하는 데는 아래와 같다.
먼저 심볼을 생성하는데 인자의 값으로는 어떤 값이든 가능하다.
그리고 콘솔을 통해서 결과를 보면 위와 같이 각 변수에는 Symbol객체로 감싸진 값들이 들어있음을 볼 수 있다.
이상한 점으로는 new를 사용하지 않는다. 이는 new연산자를 지원하지 않기 때문이라고 한다.
심볼의 타입은 어떠한가?
typeof로 확인한 결과 객체라서 object가 나올 줄 알았지만 symbol이라는 타입을 가지고 있었다.
심볼을 사용하는 법
심볼을 이용해서 Private한 멤버를 만들어보자. 목적이 Private한 접근성을 가진 멤버를 만들기 위한 목적이었으니.
obj를 콘솔로 찍어보니 두 가지의 키값이 존재한다. 하나는 심볼의 키, 나머지 하나는 pub라는 키값이 들어가 있는 것을 확인할 수 있다.
또한 마지막 콘솔의 결과를 통해서 알 수 있듯이 obj.prv로 접근하니 아직 값이 선언되지 않았다는 의미를 가진 undefined가 출력된다.
이로써 Symbol을 이용해서 일반적으로 접근하지 못하는 Private 멤버를 만들 수 있게 되었다는 것을 알 수 있다.
그렇다면 이를 이용해서 캡슐화를 실습해보도록 하자.
이렇게 사용하면 캡슐화가 완성된다.
심볼 두 개 생성
심볼을 두 개 생성한 다음 객체에 두 가지의 심볼을 접근하게 되면 과연 같은 출력을 나타낼까?
심볼 객체를 똑같이 두 가지로 만들어 객체에 접근하니 하나는 가능하고 하나는 불가능한 특성을 가지고 있다.
더 쉽게 비교해보자면
의 결과로 확연히 다르다는 것을 알 수 있다.
그렇다면 진짜로 심볼 두 개를 만들어서 객체에 접근 가능하게 못하는 것일까.
Symbol.for(key)
방금 고민했던 문제를 풀어줄 친구가 Symbol.for()이다.
Symbol.for는 전역 심볼 레지스트리에 심볼을 생성하여 코드 전역적으로 심볼을 접근 가능하게 만드는 기능이 있다.
key인자로는 일반 심볼을 생성할 때처럼 Primitive(원시적) 값을 넣으면 된다.
아까 위에서 했던 문제를 Symbol.for로 해결해보자.
다만 주의해야 할 점은 코드 전역적으로 접근이 가능하니 이름을 겹치게 심볼을 만든 경우를 대비하여 반드시 식별자를 이용하도록 권장되어있다.
강제적 값 캐스팅이 불가능한 Symbol
Symbol을 강제적으로 값을 캐스팅 하려면 불가능하다.
아래의 예시를 보고 이해하자.
심볼 자체는 값처럼은 사용되지 못하는 특성 때문에 아래와 같은 오류가 난다.
방금 오류난 줄을 간단히 표현하자면 이와 같다.
Symbol(sym) (← 객체 ) + "bol"
Symbol(123) ( ← 객체 )- 10
애초에 캐스팅할 만한 타입이 전혀 맞지 않다! 그러므로 위와 같이 사용하는 것은 금물이다!
Symbol 값 얻어보기
그럼 "저기 위의 문제를 해결할 심볼의 키값을 얻어 보는 방법이 있는가?" 에 대한 질문이라면 답은 "YES"다.
Symbol.prototype.description을 통해서 얻어 낼 수 있다.
방금 오류 났던 저 문제를 description을 통해서 얻어 내 보자.
Symbol.prototype.description을 이용하면 Symbol생성 시 지정했던 Primitive데이터를 값처럼 사용이 가능하다!
특정 객체에 Symbol이 들어있는지 확인해보기
심볼이 객체 안에 들어있는지에 대한 여부를 알아보기 위해서 필요한 메서드가 Object.getOwnPropertySymbols()이다.
사용 예를 알아보자.
Object.getOwnPropertySymbols()를 이용하면 객체에서 가지고 있는 심볼들을 배열로 리턴해 주어 얼마나 가지고 있는지 알 수 있다.
Symbol.match, Symbol.search, Symbol.replace, Symbol.split
정규표현식을 작성하여 찾고싶은 문자열 식을 작성 후 Symbol을 통해서 단어를 찾거나, 바꾸거나 나눌 수 있다. (욕 필터링 할 때 사용하면 계속 써먹을 수 있겠다. 유지 관리도 심볼 한쪽에서만 바꾸면 OK.)
객체의 .toString을 통해서 객체의 이름 변경해보기 (Symbol.toStringTag)
내가 작성한 특정 객체에 .toString의 결과에 특정 이름을 달아주게 하는 기능이 Symbol에는 구현되어있다.
후기
심볼에 대한 특징에 대해 몇 가지 알아보았다.
Symbol.iterator가 가장 유명할 텐데 난 Symbol.iterator를 처음 사용할 때 왜 객체 안에 square bracket을 사용해서 입력하는지 몰랐는데 이번 기회를 통해서 Symbol사용법을 익히니 알게 된 거 같고, Private화를 위해 사용된 목적으로 만들게 된 계기도 알게 된 것 같다.
역시 얕은 지식으로는 승부할 수 없다. 깊게 파자!
Symbol.iterator는 차후 제네레이터 또는 콜백 때쯤? 다루게 될 거 같다.
도움받은 블로그 및 Doc, 일부 사용한 코드 출처
MDN JS Symbol - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol
Symbol - JavaScript | MDN
Symbol is a built-in object whose constructor returns a symbol primitive — also called a Symbol value or just a Symbol — that’s guaranteed to be unique. Symbols are often used to add unique property keys to an object that won’t collide with keys an
developer.mozilla.org
Jong cheol, Kim님의 블로그 - ECMAScript 6 Symbol과 Symbol 프로퍼티
https://infoscis.github.io/2018/01/27/ecmascript-6-symbols-and-symbol-properties/
ECMAScript 6 Symbol과 Symbol 프로퍼티
Symbols과 Symbol 프로퍼티Symbol은 ECMAScript 6에서 도입된 Primitive 타입으로, 기존의 string, number, boolean, null, undefined와 같은 타입입니다. Symbol은 객체의 Private 멤버를 생성하는 방법으로 시작되었는데, J
infoscis.github.io
박성룡 ( Andrew park )님의 블로그 - Javascript와 심볼 Symbol
https://pks2974.medium.com/javascript%EC%99%80-%EC%8B%AC%EB%B3%BC-symbol-bbdf3251aa28
Javascript와 심볼 Symbol
자바스크립트를 처음부터 다시 공부해보려고 한다.
pks2974.medium.com
'JS' 카테고리의 다른 글
묵혔다 꺼낸 JS - Falsey, 명시적 강제 변환 (0) 2021.09.21 묵혔다 꺼낸 JS - JSON.stringify (0) 2021.09.16 묵혔다 꺼낸 JS - Array (0) 2021.09.10 묵혔다 꺼낸 JS - 박싱, 언박싱 (0) 2021.09.07 묵혔다가 꺼낸 JS - 특수한 값들(undefined, null, NaN, Infinity) (0) 2021.09.02