본문 바로가기

Language/Javascript

[Javascript] 심볼(Symbol)

728x90
반응형

지금까지 객체의 property key는 문자형으로 만들었다.

const obj = {
    1: '1입니다.',
    false: '거짓'
}

Object.keys(obj);  // ["1", "false"]

obj['1']  // "1입니다."
obj['false']  // "거짓"

숫자형이나 boolean형으로 만들어도 Object.keys로 key들을 가져오면 문자형으로 반환되며, 실제로 접근할 때도 문자형으로 접근할 수 있다.

 

 

문자형 외에 Symbol형이 가능하다. Symbol은 유일한 식별자를 만들 때 사용한다.

const a = Symbol();   // new를 붙이지 않는다!!
const b = Symbol();

console.log(a)  // Symbol()
console.log(b)  // Symbol()

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

Symbol을 만들 때 설명을 붙여줄 수도 있다. 설명을 붙여주면 디버깅 할 때 편하다.

괄호 안에 문자열을 전달해주면 되는데 이 문자열은 Symbol에 어떤 영향도 미치지 않는다.

const id = Symbol('id');
const id2 = Symbol('id');

id   // Symbol(id)
id2  // Symbol(id)

id===id2  // false
id==id2   // false

설명이 똑같은 Symbol을 두 개 만들면 생긴 것은 같지만 서로 다름을 확인할 수 있다.

 

 

Symbol을 객체의 key로 사용해보자.

const id = Symbol('id');
const user = {
    name : 'Mike',
    age : 30,
    [id] : 'myid'
}

> user      // {name: "Mike", age: 30, Symbol(id): "myid"}
> user[id]  // "myid"

Object.keys(user);     // ["name", "age"]
Object.values(user);   // ["Mike", 30]
Object.entries(user);  // [Array(2), Array(2)]
for(let a in user){ }

Object.keys(), Object.values(), Object.entries(), for .. in은 key가 Symbol형인 프로퍼티들을 건너뛴다.

이렇게 꽁꽁 숨겨져 있는 것을 어디에 쓸 수 있을까?

const user = {
    name : 'Mike',
    age : 30
}

const id = Symbol('id');
user[id] = 'myid';

user.name = 'myname';

특정 객체의 원본 데이터는 건드리지 않고 속성을 추가할 수 있다.

다른 사람이 만들어놓은 객체에 자신만의 속성을 추가해서 덮어쓰면 안 된다. 원본 객체가 어딘가에서 Object.keys()나 for .. in으로 순회하면서 데이터를 사용하고 있을 수도 있기 때문이다. 

 

 

Symbol은 이름이 같더라도 모두 다른 존재이다. 그러나 가끔 전역변수처럼 이름이 같으면 같은 객체를 가리켜야 할 때가 있다. 이럴 때 사용할 수 있는 것이 Symbol.for()이다. 

 

Symbol.for() : 전역 심볼

- 하나의 심볼만 보장받을 수 있음

- 없으면 만들고, 있으면 가져오기 때문

- Symbol 함수는 매번 다른 Symbol 값을 생성하지만,

- Symbol.for 메소드는 하나를 생성한 뒤 키를 통해 같은 Symbol을 공유

const id1 = Symbol.for('id');
const id2 = Symbol.for('id');

id1===id2;  // true

Symbol.keyFor(id1);  // "id"

이름을 얻고 싶다면 Symbol.keyFor(변수)을 사용한다.

 

전역 심볼이 아닌 심볼은 keyFor을 사용할 수 없고 변수.description을 사용한다.

const id = Symbol('id입니다.');
id.description;  // "id입니다."

 

숨겨진 Symbol key 보는 법

const id = Symbol('id');

const user = {
    name : 'Mike',
    age : 30,
    [id] : 'myid'
}

Object.getOwnPropertySymbols(user);   // [Symbol(id)]
Reflect.ownKeys(user);   // ["name", "age", Symbol(id)]
728x90
반응형