Symbol?

Parker.Park·2022년 7월 7일
0

개념

목록 보기
3/16

Symbol?

기존 iteration protocols를 작성 하던 중 먼저 symbol에 대한 정리가 필요 한거 같다고 생각하여 정리한다. 크게 생각 안했던 for...of와 for...in에서 다루다가 이곳까지 오게 될줄은 몰랐다. 코딩 공부는 예상치 못하는 지식 여행과도 같기도 하다.

Symbol은 ES6에서 새롭게 추가된 7번째 원시 데이터 타입이다. 심볼은 주로 이름의 충돌 위험이 없는 유일한 객체의 프로퍼티 키를 만들기 위해 사용한다고 한다.

primitive data type(원시값)

기존 원시값에 대해서 정리해 보자.
Javascript에서 원시값은 객체가 아니면서 메서드를 가지지 않는 데이터라고 한다. 원시값의 종류는 7가지 이며 다음과 같다.

  • String
  • Nubmer
  • boolean
  • null
  • undefined
  • bigint

원시 값은 언어 구현체의 가장 저급 단계(low level)에서 나타낸다고 한다.
원시 값은 불변하여 변형할 수 없다고 한다. 원시값 자체와 원시값을 할당한 변수를 혼동하지 않는 것이 중요하다고 한다. 예시를 들어보자.

let dog = 'dog'

console.log(dog) //'dog'
dog.toUpperCase()
console.log(dog) //'dog'

//재할당은 가능하다.(변형이 아니다.)
dog = dog.toUpperCase()
console.log(dog) //'DOG'

toUpperCase()가 기존 문자열을 변형하지 않는 것이 아니라, 'dog'는 문자열이라는 원시값이기 때문에 불변이고, javascript 원시값에는 영향을 주지 않기 때문이다.

null, undefined를 제외하고는 모든 원시값은 원시 값을 래핑하는 래퍼 객체를 갖는다고 한다.

래퍼 객체?

래퍼 객체는 원시 타입을 감싸는 객체라고 볼 수 있다. 앞에서 prototype(원시 타입의 확장)을 다룰 때 나왔던 개념이다.

let dog = 'ddoddo'

console.log(dog.toUpperCase()) //'DDODDO'

console.log(typeof dog) //'string'
console.log(dog.constructor === String) //true

여기서 dog는 'ddoddo'라는 원시 문자 데이터가 할당 된 변수이고, toUpperCase()는 dog라는 변수를 참조하여 'ddoddo'라는 원시 데이터에 접근 할 것이다. 여기서 'ddoddo'래퍼 객체인 Stirng으로 new String('ddoddo')을 생성하여 String의 prototype 메소드인 toUpperCase()를 사용한 것으로 볼 수 있다.
여기서 헷갈릴 수도 있는 것은 원시타입은 객체가 아니기 때문에 프로퍼티나 메소드를 직업 추가할 수 없다는 것이다.

let dog1 = 'ddoddo'
let dog2 = new String('ddoddo')

console.log(typeof dog1) //'string'
console.log(typeof dog2) //'object'

Symbol 래퍼 객체

위에서 얘기한 모든 원시값은 래퍼 객체를 갖는다고 했다.(null과 undefined는 제외이다.) Stirng, Number, Boolean과 같이 래퍼 객체를 생성하는 생성자 함수에 new연산자 더한다. 하지만 심볼은 new를 사용하지 않는다. 그렇기 때문에 new를 사용할 경우 에러가 난다.

let abc1 = new Symbol('abc')
//TypeError: Symbol is not a constructor

Symbol()로부터 반환되는 모든 심볼 값은 고유한 특징을 갖고 있다.
심볼 데이터 형식의 목적이라고 하면, 객체 프로퍼티에 대한 식별자로 사용된다고 하는데 와닿지 않는 부분이다.

let abc1 = Symbol('abc')
let abc2 = Symbol('abc')

console.log(abc1 === abc2) //false

같은 문자열('abc')라고 해도 매번 새로운 심볼을 생성한다.

symbol의 사용

객체의 프로퍼티 키는 모든 문자열로 만들수 있다고 한다.
symbol값 또한 객체의 프로퍼티 키로 사용할 수 있다고 한다. symbol값은 유일하기 때문에 symbol값을 갖은 프로퍼티는 어떠한 프로퍼티와 충돌하지 않는다고 한다.

dog.name = 'ddoddo'
dog[1] = 10
dog['name' + 1] = true

console.log(dog)
//{ '1': 10, name: 'ddoddo', name1: true }
const dog = {}

let mydog = Symbol('mydog')
dog[mydog] = 10

console.log(dog) //{ [Symbol(mydog)]: 10 }
console.log(dog[mydog]) //10

Symbol 객체

Symbol함수 객체를 살펴보자

Symbol객체의 프로퍼티와 매소드 Symbol객체 또한 프로퍼티와 메소드를 갖고 있는 것을 볼수 있는데, 이 중 length와 prototype을 제외하면 `well-known Symbol`이라고 불린다. 다시 이 중에 Symbol.interator와 Symbol.for 를 짚고 넘어가려고 한다.

Symbol.iterator

well-known Symbol은 자바스크립트 엔진에 상수로 존재하고 자바스크립트 엔진은 well-known symbol을 참조하여 처리를 한다고 한다. 여기서 Symbol.iterator를 프로퍼티 key로 사용한 메소드를 가지고 있다면 자바스크립트 엔진은 이터레이션 프로토콜을 따르는 것으로 간주하고 이터레이터를 동작하게 하도록 한다고 한다.
아래의 객체들은 이터레이션 프로토콜 준수하고 있으며 이터레이터를 반환한다고 한다.

//Array
Array.prototype[Symbol.iterator]
//String
String.prototype[Symbol.iterator]
//Map
Map.prototype[Symbol.iterator]
//Set
Set.prototype[Symbol.iterator]
//DOM data structure
NodeList.prototype[Symbol.iterator] HTMLCollection.prototype[Symbol.iterator]
//arguments
arguments[Symbol.iterator]

Symbol.for

Symbol.for 메서드는 주어진 키를 사용하여 심볼 레지스트리라는 곳에서 심볼을 찾고, 존재할 경우 이를 반환한다고 한다. 존재하지 않을경우 해당 키를 전역 심볼레지스트리에 새로운 심볼을 생성한다고 한다.

구문

Symbol.for(key)

예시

const dog1 = Symbol.for('ddoddo')
const dog2 = Symbol.for('ddoddo')

console.log(dog1 === dog2) //true

const cat1 = Symbol('navi')
const cat2 = Symbol('navi')

console.log(cat1 === cat2) //false

Symbol함수는 매번 다른 Symbol값을 생성하는 반면, Symbol.for 메소드는 하나의 Symbol을 생성하여 여러 모듈이 키를 통해 같은 Symbol을 공유 할 수 있다고 한다.

참조

[Symbol, MDN, 2022년07월08일 접속]
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Symbol

[7번째 타입 심볼(Symbol), poiemaweb, 2022년07월08일 접속]
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Symbol

[Primitive, MDN, 2022년07월08일 접속]
https://developer.mozilla.org/ko/docs/Glossary/Primitive

[[Javascript] 래퍼 객체 (Wrapper object),[includestdio:티스토리], MDN, 2022년07월08일 접속]
https://includestdio.tistory.com/26

[Symbol.for(), MDN, 2022년07월08일 접속]
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Symbol/for

profile
개발자준비중

0개의 댓글