DevLog

[JS] 심볼(Symbol)이란? 본문

프로그래밍 언어/Javascript | Typescript

[JS] 심볼(Symbol)이란?

김만콩 2023. 7. 18. 14:40
본 포스팅은 유튜브 코딩앙마 님의
"자바스크립트 중급 강좌 : 140분 완성" 을 듣고 정리한 개인 공부글입니다.

심볼(Symbol)

객체 프로퍼티 key는 일반적으로 문자열을 사용하지만 심볼형으로도 선언할 수 있다.

 

심볼(symbol)이란 유일한 식별자로, 

심볼을 객체 프로퍼티 key로 사용하게 되면 프로퍼티의 유일성이 보장된다.

심볼 생성하기

`const sb = Symbol(); // 심볼 생성`

심볼은 `Symbol()` 함수를 사용해서 선언한다. 이때 new 연산자는 사용하지 않음!

 

위 함수는 호출될 때마다 매번 다른 심볼 값을 생성하며,

같은 이름의 심볼을 여러 개 생성해도 다르게 인식하기 때문에 고유성을 유지할 수 있다.

 

또한 심볼을 생성할 때 선택적으로 문자열을 더해서 심볼에 대한 설명을 추가할수도 있다. (디버깅 용도)

const id = Symbol('myid'); // description: 'myid'
const user = {
	name: "mankkong",
	age: 22,
	[id]: '0707' // 심볼을 computed 프로퍼티 key로 사용
}

/*
id => Symbol(myid)
user => {name: "mankkong", age: 22, Symbol(myid): "0707"}
user[id] => "0707"
*/

 

심볼은 언제 사용할까? - Symbol key

특정 객체의 원본은 건드리지 않고 유일한 속성을 추가할 때 사용한다.

심볼을 사용하면 객체 프로퍼티 key 중복 여부를 고려할 필요나 기존 프로퍼티를 덮어 쓸 우려가 없다는 장점이 있다.

 

근데 실제로는 개발할 때 한번도 써본 적이 없.. 흠흠

 

또한 심볼 key는 일반 프로퍼티만 사용하는 객체 메소드에 영향을 주지 않는다는 특징이 있다.

이말인즉슨 일반 객체 메소드나 `for...in` 반복문 등으로는 심볼 값에 접근할 수 없다는 뜻!

const id = Symbol('id');
const user = {
	name: "yebin",
	age: 22,
	[id]: 'mango' // 심볼
}

// 일반 객체 메소드로 탐색
Object.keys(user); // -> 심볼 제외 ["name", "age"]만 나옴

 

숨겨진 Symbol key를 보기 위해서는

`Object.getOwnPropertySymbols()`, `Reflect.ownKeys()` 메소드를 사용할 수 있다.

// Object.getOwnPropertySymbols() -> 심볼만 반환
Object.getOwnPropertySymbols(user); // -> [Symbol(id)]

// Reflect.ownKeys() -> 심볼 포함 모든 키 반환
Reflect.ownKeys(user); // -> ["name", "age", Symbol(id)]

 

일반 심볼 vs. 전역 심볼

전역 심볼 같은 이름이 같은 개체를 가지는 경우를 말한다.

 

일반 심볼의 경우 같은 이름이더라도 다른 심볼로 구분되지만,

전역 심볼은 같은 이름으로 동일한 하나의 심볼에 접근할 수 있다.

 

`Symbol.for()` : 없으면 만들고, 있으면 가져온다!

심볼을 생성한 뒤 를 통해 같은 객체를 공유함으로써 하나의 심볼을 보장받을 수 있다. 

// 일반 심볼
const s1 = Symbol("symbol");
const s2 = Symbol("symbol");

s1 === s2; // false

// 전역 심볼 -> 코드 어디에서나 사용 가능
const id1 = Symbol.for("id");
const id2 = Symbol.for("id");

id1 === id2; // true

`Symbol.keyFor()` 메소드로 전역 심볼의 키를 받아올 수 있다.

일반 심볼의 경우에는 위 메소드를 사용할 수 없으며, 대신 description을 받아올 수 있는 방법이 존재한다.

// 전역 심볼 키 받아오기
Symbol.keyFor(id1) // "id"

// 일반 심볼 description 받아오기
s1.description; // "symbol"