JS 중급 | 심볼 (symbol)

uoah·2023년 1월 12일

자바스크립트

목록 보기
19/33
post-thumbnail

🚀 오늘의 학습 목표

  • 심볼 (symbol)

객체 property key 는 오직 문자형 과 아래에서 배울 심볼형(symbol) 만을 허용한다.

const obj = {
  1: '1이다',
  false: '거짓',
}

const name = Object.keys(obj);

console.log(name); // ["1","false"]

console.log(obj['1']); // "1이다."
console.log(obj['false']); // "거짓"

4. 심볼 (symbol)

자바스크립트의 심볼(Symbol)은 ES6에서 새롭게 추가되었으며, "심볼" 데이터 형식은 값으로 익명의 객체 속성(object property)을 만들 수 있는 특성을 가진 원시 데이터 형식(primitive data type)이다.

심볼은 아래와 같이 만든다.

심볼은 유일한 식별자를 만들 때 사용한다.
symbolnew 를 붙이지 않는다.

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

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

console.log(a === b); // false
console.log(a == b); // false

심볼형은 유일성 이 보장된다. 전체의 코드 중에 하나라는 뜻이다.
심볼을 만들 때 설명을 붙여 줄 수 있고 이는 디버깅*을 할 때 편리하다.

디버깅*이란 무엇인가요?

디버깅은 모든 소프트웨어에서 소스 코드의 오류 또는 버그를 찾아서 수정하는 과정이다. 소프트웨어가 예상대로 작동하지 않으면 컴퓨터 프로그래머는 오류가 일어나는 원인을 알아내기 위해 코드를 분석한다.

const id = symbol('id');

설명에는 문자열을 전달해 주면 되는데, 이 문자는 심볼 생성에는 어떠한 영향도 주지 않는다.
설명이 똑같은 걸 또 만들어도 둘다 다르다(false)고 나온다.

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

console.log(id1); //Symbol(id)
console.log(id2); //Symbol(id)

console.log(id1 === id2);	//fasle
console.log(id1 == id2); 	//fasle

4-1. property key : 심볼형

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

console.log(user);		// {name: 'mike', age: 30, Symbol(id): 'myid'}
console.log(user[id]); 	// "myid"

아래의 메서드들은 key 가 symbol형 인 애들은 건너뛴다.
마찬가지로 for...in 을 써도 건너 뛴다.

Object.keys(user); 		// ["name","age"]
Object.values(user); 	// ['mike', 30]
Object.entries(user);	// [Array(2), Array(2)]

for(let a in user){
  console.log(a); 
  // "name" 
  // "age"
}

❓ 심볼(symbol) 은 어디에서 쓸까?

'심볼(symbol)'은 유일한 식별자(unique identifier)를 만들고 싶을 때 사용합니다.

특정 객체의 원본 객체는 건드리지 않고 속성을 추가할 수 있다.
다른 사람이 만들어 놓은 객체에 객체 자신만의 속성을 추가해서 덮어 씌우면 안 되기 때문이다.
원본 데이터가 다른 데서 쓰이고 있는데, 내가 추가한 프로퍼티가 예측 불가능하게 튀어 나오면 안 되기 때문이다.

4-2 symbol.for() : 전역 심볼

  • 하나의 심볼만 보장 받을 수 있다.
  • 없으면 만들고, 있으면 가져오기 때문이다.
  • 심볼 함수는 매번 다른 심볼 값을 생성하지만,
  • symbol.for 메서드는 하나를 생성한 뒤 키를 통해 같은 심볼을 공유한다.
const id1 = Symbol.for('id');
const id2 = Symbol.for('id');

console.log(id1 === id2); // true

아까와 다르게 id1 과 id2 가 동일하다고 나타난다.
이것을 전역 심볼이라고 부르며, 코드 어디에서든 사용할 수 있다.

이름을 얻고 싶다면 Symbol.keyFor() 를 사용하면 된다.

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

4-3. description

전역 심볼이 아닌 심볼은 keyFor 을 사용할 수 없다.
대신 discription 으로 알 수 있다.

const id = Symbol('id다');
console.log(id.description); // 'id다'

4-4. 숨겨진 Symbol key 보는 법

심볼을 완벽히 숨길 수 있는 방법은 없다.

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

// 심볼들만 볼 수 있다.
Object.getOwnPropertySymbols(user); // [Symbol(id)]

// 심볼형 키를 포함한 객체의 모든 키를 보여 준다.
Reflect.ownKeys(user);				// ['name', 'age', Symbol(id)]

다만, 대부분의 라이브러리들은 해당 메서드를 많이 사용하지 않기 때문에 걱정하지 말고 유일한 프로퍼티를 사용하고 싶을 때 심볼을 사용하자.


🧑🏻‍💻 예제로 쉽게 이해하기

아래 다른 개발자가 작성한 코드에 메서드를 추가 하여 보자.

// 다른 개발자가 만들어 놓은 객체
const user = {
  name : 'mike',
  age : 30,
};

// 내가 새롭게 하는 작업
user.showName = function(){}

// 사용자가 접속하면 보는 메시지
for (let x in user) {
  console.log(`His ${x} is ${user[x]}.`);
}
/*
"His name is mike."
"His age is 30."
"His showName is function () {}."
*/

❌ 심볼을 사용하지 않았을 경우 내가 새롭게 작업한 코드로 인해 나오지 말아야 할 문구 ("His showName is function () {}.") 가 나오는 문제가 발생한다.

위 문제를 심볼을 사용하여 고쳐 보자.

// 다른 개발자가 만들어 놓은 객체
const user = {
  name : 'mike',
  age : 30,
};

// 내가 새롭게 하는 작업
const showName = Symbol('showName');
user[showName] = function (){
  console.log(this.name);
}
user[showName] ();

// 사용자가 접속하면 보는 메시지
for (let x in user) {
  console.log(`His ${x} is ${user[x]}.`);
}
/*
"mike"
"His name is mike."
"His age is 30."
*/

이렇게 하면 내가 새롭게 작업한 메서드도 잘 작동하며, 다른 개발자가 작성한 코드에도 영향을 미치지 않고 메서드를 추가할 수있다.

동일한 메서드가 있는지를 걱정할 필요도 없고, 다른 개발자가 만들어 놓은 프로퍼티에 덮어씌울 일이 없다는 것이 심볼의 장점이다.

0개의 댓글