일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 무한 스크롤
- Jest
- ESlint
- map
- Cypress
- async/await
- CORS
- RTK Query
- useAppDispatch
- 호이스팅
- React
- app router
- 인터섹션
- 이분 검색
- 태그된 유니온
- 공변성
- tailwind
- 반공변성
- autosize
- 타입 좁히기
- TS
- CI/CD
- recoil
- webpack
- 투포인터
- Promise
- 결정 알고리즘
- dfs
- SSR
- 리터럴 타입
- Today
- Total
짧은코딩
자바스크립트-심볼형 본문
심볼형
자바스크립트는 객체 프로퍼티 키로 문자형과 심볼형만 허용한다.
-심볼(symbol)
심볼은 유일한 식별자를 만들고 싶을 때 사용한다.
Symbol()을 사용하면 심볼값을 만들 수 있다.
// 심볼 id에는 "id"라는 설명이 붙습니다.
let id = Symbol("id");
심볼 이름은 디버깅 시 아주 유용하다.
심볼은 유일성이 보장되는 자료형이라 설명이 같은 심볼이 여러 개라도 각 심볼값은 다르다.
let id1 = Symbol("id");
let id2 = Symbol("id");
alert(id1 == id2); // false
따라서 같은 설명이라도 비교하면 false가 나온다.
- 심볼은 문자형으로 자동 형 변환되지 않는다.
let id = Symbol("id");
alert(id); // TypeError: Cannot convert a Symbol value to a string
alert(id.toString()); // Symbol(id)가 얼럿 창에 출력됨
alert(id.description); // id
그냥 id로만 출력하면 에러가 난다.
toString()를 사용하면 Symbol(id)가 출력된다.
description을 사용하면 설명인 id를 출력한다.
-'숨김' 프로퍼티
심볼을 이용하면 '숨김' 프로퍼티를 만들 수 있다. 숨김 프로퍼티는 외부 코드에서 접근이 불가능하고 값을 덮어쓸 수 없는 프로퍼티이다.
let user = { // 서드파티 코드에서 가져온 객체
name: "John"
};
let id = Symbol("id");
user[id] = 1;
alert( user[id] ); // 심볼을 키로 사용해 데이터에 접근할 수 있습니다.
이 코드의 결과는 1이 나온다.
Symbol("id")을 사용한 이유는 user의 서드파티 코드에서 가지고 온 객체라서 함수로 프로퍼티를 추가할 수 없다.
하지만 심볼은 서드파티 코드에 접근 가능해서 심볼을 사용하면 서드파티 코드가 모르게 user에 식별자 부여가 가능하다.
만약 스크립트(라이브러리 등)에서 user를 식별해야 하는 상황이 있다. 근데 서로의 코드를 모른 채 user를 식별해야 하면 Symbol을 이용해 전용 식별자를 만들 수 있다.
// ...
let id = Symbol("id");
user[id] = "제3 스크립트 id 값";
-Symbols in a literal
let id = Symbol("id");
let user = {
name: "John",
[id]: 123 // "id": 123은 안됨
};
객체 리터럴 {}을 사용해 객체를 만들면 대괄호를 사용해 심볼형 키를 만들어야 한다.
-심볼은 for..in에서 배제된다.
let id = Symbol("id");
let user = {
name: "John",
age: 30,
[id]: 123
};
for (let key in user) alert(key); // name과 age만 출력되고, 심볼은 출력되지 않습니다.
// 심볼로 직접 접근하면 잘 작동합니다.
alert( "직접 접근한 값: " + user[id] );
for in으로 접근하면 심볼은 나오지 않는다. 따라서 심볼에 접근하고 싶으면 직접 접근해야 한다.
let id = Symbol("id");
let user = {
[id]: 123
};
let clone = Object.assign({}, user);
alert( clone[id] ); // 123
하지만 모든 객체를 반환하는 assign 함수는 심볼 프로퍼티도 복사한다.
-전역 심볼
애플리케이션 곳곳에서 "id" 심볼을 이용해 특정 프로퍼티에 접근해야 하면 이름이 같은 심볼이 같은 개체를 가리키게 해야한다.
그래서 전역 심볼 레지스트리가 만들어졌다. 전역 심볼 레지스트리에 심볼을 만들고 접근하면 항상 동일한 심볼을 반환해준다.
레지스트리 안에 심볼을 읽거나 생성하려면 Symbol.for(key)를 사용하면 된다.
// 전역 레지스트리에서 심볼을 읽습니다.
let id = Symbol.for("id"); // 심볼이 존재하지 않으면 새로운 심볼을 만듭니다.
// 동일한 이름을 이용해 심볼을 다시 읽습니다(좀 더 멀리 떨어진 코드에서도 가능합니다).
let idAgain = Symbol.for("id");
// 두 심볼은 같습니다.
alert( id === idAgain ); // true
두 심볼을 비교하면 같은 값이 나오게된다.
-Symbol.keyFor
전역 심볼에서 Symbol.keyFor을 사용하면 이름을 얻을 수 있다.
// 이름을 이용해 심볼을 찾음
let sym = Symbol.for("name");
let sym2 = Symbol.for("id");
// 심볼을 이용해 이름을 얻음
alert( Symbol.keyFor(sym) ); // name
alert( Symbol.keyFor(sym2) ); // id
만약 전역 심볼이 아닌 심볼에서 얻고 싶으면 description 프로퍼티를 사용한다.
let globalSymbol = Symbol.for("name");
let localSymbol = Symbol("name");
alert( Symbol.keyFor(globalSymbol) ); // name, 전역 심볼
alert( Symbol.keyFor(localSymbol) ); // undefined, 전역 심볼이 아님
alert( localSymbol.description ); // name
'JS' 카테고리의 다른 글
async와 await (0) | 2022.06.03 |
---|---|
Promise (0) | 2022.06.03 |
자바스크립트-옵셔널 체이닝 '?.' (0) | 2022.05.14 |
자바스크립트-new 연산자와 생성자 함수 (0) | 2022.05.14 |
자바스크립트-메서드와 this (0) | 2022.05.14 |