객체의 키는 주로 문자형으로 생성하고 접근한다.
아래 예제를 보면 숫자형과 불린형으로 key로 넣어 객체를 반환할때 문자형으로 반환되는 것을 볼 수 있다.
실제로 접근할 때도 문자형으로 접근할 수 있다.
const obj = {
1: '숫자 1',
false: '거짓',
}
console.log(Object.keys(obj)); //['1', 'flase'] 반환
console.log(obj['1']); // '숫자 1' 반환
// 숫자형 1과 불린형 false 를 key 값으로 넣어지만 문자형으로 전환되면서 반환
심볼형이란?
문자형으로 객체 프로퍼티 키를 반환하는것도 가능하고 한개 더 가능한것이 원시형 타입중 하나인 '심볼형' 이다.
심볼은 유일한 식별자를 만들때 주로 사용한다. 이 말이 좀 어려운데 예를 들어 내가 ID 를 만드는 것이랑 같다.
아래 예제를 보면 같은 심볼 처럼 보이지만 일치 연산자를 사용하면 false 를 반환한다. 둘은 같아 보이지만 전혀 다른 심볼이다.
심볼형은 '유일성' 이 보장되어 생성할때마다 매번 다른 심볼을 만들어 낸다 이 말은 즉, 전체 코드 중에 딱 하나만 존재한다는 것이다.
한줄로 요약하자면 변경 불가능한 원시 타입의 값이며, 다른 값과 중복되지 않는 고유한 값이다.
const a = Symbol('심볼입니다.');
const b = Symbol ('심볼입니다.');
console.log(a === b); // false 반환
( )괄호 안에 있는것은 설명문구로 주로 디버깅을 할때 사용된다. 안에 있는 문자열을 심볼 생성중에 어떤영향도 끼치지 않는다 주석 역할을 한다고 생각하면 된다.
심볼형으로 프로퍼티 키 만들기
심볼형을 객체의 키로 사용할때는 computed property 를 사용 하여 [ ]대괄호 안에 넣어야한다. 그냥 넣게 되면 문자열로 인식해서 심볼형이라고 인식하지 않는다.
const id = Symbol('심볼입니다');
const obj = {
name: 'Mike',
age: 33,
[id]: 'myId',
}
console.log(obj[id]); //'myId' 반환
심볼 key ,value 확인하기
객체에서 key 와 value 또는 둘다 반환하기 위해서 존재하는 메소드가 있다.
Object.keys , Object.values , Object.entries 이다. 이것들을 활용해서 심볼형으로 만든 키와 값에 접근하려고 하면 어떻게 될까?
const id = Symbol('심볼입니다');
const obj = {
name: 'Mike',
age: 33,
[id]: 'myId',
}
console.log(Object.keys(obj)); // ['name', 'age'] 만 반환
console.log(Object.values(obj)); // ['Mike', 33] 만 반환
console.log(Object.entries(obj)); //[['name', 'age'], ['Mike', 33]] 만 반환
for (let a in obj) {
console.log(a);
} // 'name'과 'age' 만 반복
//symbol에 접근하는 메소드
console.log(id.description); // '심볼입니다' 반환
위 코드에서 보는것처럼 심볼형으로 만든 키와 값은 반환되지 않는다. 심볼형은 숨겨지는 특징을 가지고 있다.
숨겨진 심볼은 description 을 통해 접근이 가능하다.
symbol 은 언제 사용될까?
꽁꽁 숨겨져 있는 심볼을 대체 왜 사용하는걸까? 보통 원본 데이터(남이 사용하는) 를 망치지 않고 사용하고 속성을 추가하고 싶을때 사용한다. 예를들어 멋대로 id.name = 'mike' 이런식으로 프로퍼티를 추가해버리면 기존에 원본데이터 키와 값으로 순회하고 있는 코드를 망칠수도 있기 때문이다. 주로 키끼리의 충돌 가능성을 없기 때문에 충돌 위험이 없는 유일한 객체의 프로퍼티 키를 만들기 위해 사용한다.
또한 심볼의 숨겨지는 특징을 사용하여 외부로 노출할 필요가 없는 프로퍼티를 생성할때 사용한다.
더 쉬운 이해를 위해 아래 코드를 한번 보자,
추가 작업으로 인해 사용자가 보면 안되는 메시지가 엉뚱하게 노출되는 상황이 발생했다. 이럴때 사용하는게 심볼형이다.
// 다른 개발자가 만든 객체
const user = {
name: 'Mike',
age: 30,
}
// 추가 작업
user.showName = function () {};
// 사용자가 접근하면 보이는 메세지
for(let key in user){
console.log(`user ${key} is ${user[key]}`);
}
// "user name is Mike" , "user age is 30" 이 반복되고 난 후
// 추가 작업한 "user showName is function () {}" 라는 사용자가 보면 안되는 메세지가 반환
이럴때 사용하는게 심볼형이다. 유일한 식별자인 심볼을 사용하여 다른 개발자가 만든 객체를 덮어쓸 일도 없으면서 사용자에게 노출되지 않는것을 볼 수 있다.
// 다른 개발자가 만든 객체
const user = {
name: 'Mike',
age: 30,
}
// 추가 작업
const showName = Symbol('show name'); // 심볼을 생성
user[showName] = function() {}; // 사용자에게 노출되지 않는 심볼을 객체에 추가
// 사용자가 접근하면 보이는 메세지
for(let key in user){
console.log(`user ${key} is ${user[key]}`);
}
Symbol.for() 전역 심볼
Symbol.for() 메소드는 인자로 전달받은 문자열이 key가 되고 Symbol() 로 생성한 값이 value 가된다. 이렇게 만들어진 Symbol은 *전역 심볼 레지스트리에 저장된다.
*전역 심볼 레지스트리란 생성된 심볼 값을 관리하하는 저장소로 Symbol.for() 메소드로 생성된 심볼값만 관리한다.
기존 Symbol() 함수와의 차이점은
- 호출할시 성공하면 생성했던 심볼값을 반환하고 실패하면(존재하지 않으면) 새로운 심볼값을 생성한다.
- 위의 이유때문에 하나의 심볼만 보상받을 수 있다.
- 기존 Symbol() 함수는 매번 다른 값을 생성하지만, Symbol.for() 메소드는 key(인자로 전달받은 문자열) 를 통해 같은 Symbol을 공유한다.
const a = Symbol.for('심볼입니다.');
const b = Symbol.for('심볼입니다.');
console.log(a === b); //true 반환
console.log(Symbol.keyFor(a)); //'심볼입니다.' 반환
기존 심볼 함수를 만들었을때와는 정 반대로 true 를 반환하다. 같은 키값(인자)를 가지고 있기 때문이다.
전역 심볼에 접근하기 위해선 위 코드처럼 Symbol.keyFor() 메소드를 사용할 수 있다.
심볼형을 공부하기 있는 현재 시점 솔직히 아직 완벽하게 이해가 되지는 않았다.. 유일한 식별자를 생성할때 사용하는 심볼을 얼마나 이용할지 의문이긴하지만 지금 공부해 두면 나중에 아 이런게 있었지! 하고 꺼낼 쓸 날이 오지 않을까..? (머리 뽀개지는중)
'dev > JavaScript' 카테고리의 다른 글
[간단 프로그램] 글자수 제한 (0) | 2023.03.28 |
---|---|
[간단 프로그램]lotto 프로그램 만들기 (0) | 2023.03.28 |
객체에서 쓸 수 있는 메소드들 (0) | 2023.02.18 |
계산된 프로퍼티 computed property (0) | 2023.02.17 |
객체 object (0) | 2023.02.11 |
댓글