ES6알아보기 12 - Symbol
Symbol 이란?
Symbol 이란 ES6 에서 추가된 Primative Data Type(원시 자료형) 입니다.
이미 Ruby 나 Objective-c 같은 언어들에서 차용되고 있는 걔념이기에 익숙하신 분들도 많겠지만, Javascript 개발자에게는 기존의 문법과 연관성이 없어보이는 사용법? 과 새로운 원시타입이라는 점 때문에 생소하게 느껴질 수도 있을 것 같습니다.
자료형을 확인해 보겠습니다.
// 원시타입
typeof 10 // 'number'
typeof 'hello' // 'string'
typeof true // 'boolean'
typeof undefined // 'undefined'
typeof Symbol() // 'symbol' ES6에서 새로 추가
// 객체타입
typeof {} // 'object'
typeof function () {} // 'function'
Symbol 타입의 기본 사용법
위에서도 확인했지만 Symbol 타입은 Symbol() 함수를 실행해서 생성할 수 있습니다.
Symbol 은 이름에서도 유추해 볼 수 있듯이 각각의 Symbol 객체는 모두 유니크한 값을 가지고 있습니다.
assert.notEqual(Symbol(), Symbol())
assert.notEqual(Symbol('foo'), Symbol('foo'))
이런 특수성 때문에 가장 흔히 Symbol 을 사용하는 경우는 객체의 프로퍼티를 지정해 줄 때 입니다.
var obj = {}
obj['foo'] = 10
obj[Symbol('foo')] = 20
obj[Symbol('foo')] = 30
console.log(obj)
// { foo: 10, [Symbol(foo)]: 20, [Symbol(foo)]: 30 }
보통의 경우 객체에 동일한 키값을 가진 프로퍼티를 나중에 정의한 프로퍼티가 덮어쓰기 되지만, Symbol의 경우는 얼마든지 동일한 프로퍼티? 를 선언할 수 있습니다.
반대로 정의한 프로퍼티를 읽기 위해서는 어떻게 해야 할까요?
var obj = {}
// 잘못된 예
obj[Symbol('foo')] = 10
console.log(obj[Symbol('foo')]) // undefined
// 정의한 변수를 대입해서 불러오기
var bar = Symbol('bar')
obj[bar] = 20
console.log(obj[bar]) // 20
// Object.getOwnPropertySymbols() 를 사용해 불러오기
var [foo, bar] = Object.getOwnPropertySymbols(obj)
console.log(obj[foo]) // 10
console.log(obj[bar]) // 20
Global Symbol 사용하기
다음으로 알아볼 기본적인 사용법은 전역객체로써의 Symbol 사용법입니다.
전역으로써의 Symbol을 정의하고 불러오는 방법은 아래와 같습니다.
// 전역심볼 정의하기
var global1 = Symbol.for('foo')
// 정의한 심볼을 Global Symbol Registry 에서 불러오기
var global2 = Symbol.for('foo')
// global1 and global2 is equal
assert.equal(global1, global2)
Symbol()
로 함수를 실행했을 경우에는 매번 새로운 Symbol 을 반환한다는 것을 앞에서 알아보았습니다.
하지만 Global Symbol 은 이와는 달리 Symbol.for([키값])
을 통해서 같은 키값은 가진 글로벌 심볼이 있는지 먼지 Global Symbol Registry 를 검색하고, 없을 경우 새로운 글로벌 심볼을 생성하여 반환합니다.
여기서 Global Symbol Registry 는 브라우저의 글로벌 객체인 window 나 node.js 의 global 객체안에 소속되었다고 생각하실 수도 있지만, 이 GSR 은 좀더 상위인 JS engine 자체에서 관리가 되고 있기 때문에 ~더 글로벌한~ 곳에서 관리되고 있다고 생각하면 될 것 같습니다.
한가지 더 추가로 global symbol 객체가 가지고 있는 키값은 아래와 같은 방법으로 찾을 수도 있습니다.
var global = Symbol.for('foo')
var key = Symbol.keyFor(global)
console.log(key) // 'foo'
이렇게 개발자가 직접 글로벌 심볼을 Global Symbol Registry 에 추가할 수 있지만, 이미 ES6 사양과 함께 이미 들어가 있는 글로벌 심볼들도 있는데 이걸 well-known Symbols 라고 부릅니다.
다음시간에는 이 well-knowm symbols 들을 살펴보면서, 더 똑똑하게 javascript 를 사용하는 방법을 알아보도록 하겠습니다.