24. 심볼형

Chipmunk_jeong·2021년 3월 1일
0

TIL

목록 보기
24/62
post-thumbnail

자바스크립트 객체의 프로퍼티 키는 오직 문자형만을 허용하는데, 추가적으로 한가지 더 가능하다.
그것이 바로 심볼형이다.


심볼

심볼은 유일한 식별자를 만들고 싶을 때 사용한다.

심볼은 Symbol()의 문법을 사용한다.
심볼을 만들 때는 심볼 이름이라고 부르는 설명을 붙일 수 있다.
심블의 이름은 디버깅에서 유용하게 사용한다.

// 심볼id에는 "id"라는 설명이 붙는다.
let id = Sumbol('id');

심볼은 유일성이 보장되는 자료형이다.
설명이 동일한 여러개의 심볼을 만들어도 다 다른값이 된다.
심볼에 붙이는 설명은 그저 이름표 역활만 할 뿐이다.

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

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

심볼은 문자형으로 자동 형 변환(x)

자바스크립트에서는 문자형으로 암시적 형 변환이 자유롭게 일어난다.
하지만 심볼은 예외적이다. 심볼형 값은 다른 자료형으로 자동 형변환이 일어나지 않는다.

let id = Symbol('id');
alert(id); // TypeError

alert는 매개변수를 문자형으로 자동 형 변환을 하기 때문에
Symbol형이 들어오면 에러가 발생한다.

문자열과 심볼은 근본이 다르기 때문에 서로의 타입으로 변환돼선 안된다.
언어 차원의 보호장치를 마련하여 심볼형이 다른 형으로 변환되지 않게 막아준다.
심볼을 반드시 출력해줘야 한다면 .toString()메서드를 명시적으로 호출해 주면 된다.

let id = Symbol('id');
alert(id.toString());

또한 .description을 사용하면 설명만을 보여줄 수 있다.

let id = Symbol('id');
alert(id.description);

심볼은 숨겨진 프로퍼티

심볼을 이용한다면 숨김(hidden) 프로퍼티를 만들 수 있다.
숨김 프로퍼티는 외부 코드에서 접근이 불가능하고 덮어쓰기도 불가능하다.

서드파티 코드(외부에서 만들어진 라이브러리 등)에서 가져온 user라는 객체가 여러개 있고, user를 이용해 작업을 해야하는 상황이라고 가정하고, user에게 식별자를 붙여준다면

let user = { // 서드파티 코드에서 가져온 객체
  name: 'quakka'
};
let id = Symbol("id");

user[id] = 1;

alert(user[id]); // 심볼을 키로 사용하여 데이터에 접근할 수 있다.

여기서 식별자를 심볼형으로 사용한 이유는?

우선 user는 외부에서 가지고 온 객체이다. 마음대로 프로퍼티를 추가할 수 없기 때문에 심볼을 사용했다.
심볼은 서드파티 코드에서 접근할 수 없기 때문에, 우리만 아는 식별자를 추가할 수 있는 것이다.
이것은 해당 user라는 객체를 여러곳에서 사용할 때 더 유용한다.
만약 서드파티 코드, 현재 작성 중인 스크립트, 다른 제3의 스크립트에서 해당 user객체를 식벼해야하는 상황이라면
문자열로 'id'를 주는것은 위험하다. 덮어쓰기가 될 수 있기 때문이다.
이러한 상황에서도 심볼타입을 준다면 완벽히 구분할 수 있다.


심볼은 for...in에서 배제

키가 심볼일 경우는 for...in 반복문에서 배제된다.

let id = Symbol("id");
let user = {
  name: "quakka",
  age: 29,
  [id]: 123   // 리터럴에서 심볼을 주기위해 대괄호를 사용
};

for(let key in user) { console.log(key) };
//name, age

하지만! Object.assign을 사용하면 심볼 또한 포함되어 복사가 된다.


전역 심볼

심볼은 이름이 같더라도 다른것으로 인식된다.
하지만 이름이 같은 심볼이 같은 개체를 가르키길 원하는 경우도 있다.
애플리케이션 곳곳에서 심볼 "id"를 이용해 특정 프로퍼티에 접근해야 한다면, 전역 심볼 레지스트리를 이용한다.

전역 심볼 레지스트리 안에 심볼을 만들고 해당 심볼에 접근하면, 이름이 같은 경우 항상 동일한 심볼을 반환한다.

전역 심볼 레지스트리에 새로운 심볼을 생성하려면
Symbol.for(key)를 사용하면 된다.
만약 해당 key의 심볼이 존재한다면 그 심볼을 읽어온다.

//전역 레지스트리에서 심볼을 읽는다.
let id = Symbol.for("id"); // 만약 없다면 생성 후 읽어온다.
//동일한 key를 이용해 같은 심볼을 읽어 온다.
let idAgain = Symbol.for("id"); 

console.log(id === idAgain); // true

심볼의 이름을 읽어오기 위해서는 Symbol.keyFor(key)를 사용한다.

// 전역 심볼을 읽음 또는 생성 후 읽음
let sym1 = Symbol.for("name");
let sym2 = Symbol.for("id");

// 전역에서 받아온 심볼의 이름을 읽음
console.log(Symbol.keyFor(sym1)); // name
console.log(Symbol.keyFor(sym2)); // id

전역심볼이 아닐경우에는 undefined가 반환됨
전역심볼이 아닐경우에는 .description으로 접근

profile
Web Developer

0개의 댓글