JavaScript - Symbol


Symbol은 ES6에서 새로 등장한 데이터 타입이다.

기존에는

밑은 Primitive Value
number
string
boolean
null
undefined
Symbol

밑은 참조형 데이터
object
array
function

Map
Set
WeakMap
WeakSet

TypedArray
ArrayBuffer
  • primitive value => 유일무이하고 고유한 존재(private을 해결하기 위해 만들어짐)
  • 비공개 멤버에 대한 needs에서 탄생
  • 기본적인 열거대상에서 제외(for in문으로 프로퍼티에 접근안됨)
    const obj2 = {
      [Symbol('2')] : true,
      '02': true,
      '10': true,
      '01': true,
      '2': true,
      [Symbol('1')]: true
    }
      
    const keys2 = []
    for(const key in obj2){
      keys2.push(key)
    }
      
    keys2 //["2", "10", "02", "01"]. symbol 안들어갔다.
    
  • 암묵적 형변환 불가
const a = Symbol()

'a'+1 //"a1"
true+1 //2
Symbol()+1 // error

const a = Symbol()
const b = Symbol()

a === b //false
a == b //false

//네이밍 할당 가능
const a = Symbol('a')
const b = Symbol('a')

a === b //false
a == b //false

const c= b
b === c //true

const x = () => {
  const a = Symbol('a');
  return {
    [a]: 10
  }
}

const y = x();

y.a //안됨
y['a']//안됨

const x = () => {
  const a = Symbol('a');
  return {
    [a]: 10
    a: a //접근할 수 있게 해줌
  }
}

y.a //Symbol(a)

위의 것을 보면 은닉화에 성공한 것을 알 수 있다. 값도 적고 눈에 보이지만 public에서 볼 수 있는 권한은 주냐 마냐에 따라 달라진다.

const b = Reflect.ownKeys(y)//그냥 개발 용도로 쓰인다. 
y[b[0]] // 10 . 접근 가능하긴 하다.

Symbol은 new 연산자 못 쓴다.

new Symbol() // Symbol is not a constructor
  • Symbol([string])
const obj = {a:1}
const sb1 = Symbol(obj)
const sb2 = Symbol(obj) //toString 처리되어 들어간다.

sb1 // Symbol([object Object])

const sb = Symbol(null)
sb // Symbol(null) 문자열로 들어갔다.

객체 프로퍼티 키로 활용한다.

const NAME = Symbol('이름')
const GENDER = Symbol('성별')
const iu = {
  [NAME]: '아이유'
  [GENDER]: 'female',
  age: 26
}

// age:26, Symbol(이름): "아이유", Symbol(성별):"female"

for(const prop in iu){
  console.log(prop, iu[prop]) 
}
//age 26만 나온다.