심볼(Symbol)

라용·2022년 7월 29일
0

인프런 강의 자바스크립트 중급 - 코딩앙마 를 듣고 정리한 내용입니다.

객체 프로퍼티의 key 는 문자형으로 가져오고, 문자형으로 호출합니다.

const obj = {
	1: '1입니다.',
	false: '거짓'
}
Object.keys(obj); // ["1", "false"]

// 호출할 때도 문자열로

obj['1'] // "1 입니다."
obj['false'] // "거짓"

심볼 Symbol 은 유일한 식별자를 만들 때 사용합니다.

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

// 이렇게 두번 할당하면 값은 똑같지만 

console.log(a) // -> Symbol()
console.log(b) // -> Symbol()

// 일치, 동등 연산자 모두 false 가 나옵니다.

a === b // -> false
a == b // -> false

Symbol 은 유일성이 보장됩니다. 전체 코드 중 딱 하나만 존재합니다. 아래와 같이 Symbol 에 설명을 붙일 수도 있습니다. 설명을 붙여야 디버깅할 때 편합니다.

const id = Symbol('myid');

심볼을 객체의 key 로 넣으면 객체에는 잘 들어가지만 기타 메소드나 for in 문에는 추출되지 않습니다.

const id = Symbol('id');
const user = {
	name: 'Mike',
	age: 30,
	[id]: 'myid'
}
user
-> {name: 'Mike', age: 30, Symbol(id): 'myid'}
// 위처럼 객체에는 들어감

Object.keys(user);
Object.values(user);
Object.entries(user);
for(let a in user) 
// 이런 식으로 출력은 안됨

그래서 심볼을 쓰면 원본 데이터를 건드리지 않고 속성을 추가할 수 있습니다.

const user = {
	name: 'Mike',
	age: 30
}
const id = Symbol('id'); // 심볼 선언
user[id] = 'myid'; // 객체에 추가

다른 사람이 만든 객체에 자신만의 속성을 덮어 쓰면 안됩니다. 그렇다고 엄청 길고 이상한 네이밍을 달아도 좋지 않습니다. 원본 객체의 데이터를 어디선가 사용하고 있을 수 있습니다.

전역심볼인 Symbol.for() 을 사용하면 하나의 심볼만 보장받을 수 있습니다. 없으면 만들고 있으면 가져옵니다. Symbol 은 매번 다른 Symbol 값을 생성하지만 Symbol.for() 메소드는 하나를 생성한 뒤 키를 통해 같은 Symbol 을 공유합니다.

const id1 = Symbol.for('mid');
const id2 = Symbol.for('mid');

id1 === id2;  //-> true

// 심볼의 이름을 알고 싶다면

Symbol.keyFor(id1) // "mid"

// 전역심볼이 아니면 keyFor 을 사용할 수 없으니 description 을 사용합니다.

const id = Symbol('id 입니다.');
id.description; // "id 입니다."

심볼을 완전히 숨길 순 없습니다.

Object.getOwnPropertySymbols(user);  // -> [Symbol(id)]
Reflect.ownKeys(user);  //-> ["name", "age", Symbol(id)]

위와 같은 방식으로 심볼을 불러오거나 배열에 함께 담을 수 있지만 대부분의 라이브러리, 내장함수는 이런 메소드를 사용하지 않으니 유일한 프로퍼티를 사용하고 싶을 때 심볼을 활용하면 좋습니다.

예시를 통해 살펴보면

// 다른 개바라가 만들어 놓은 객체
const user = {
	name: "MIke",
	age: 30,
};

// 새로 추가
user.showName = function () {}
// 이렇게 추가하면 이상한 객체값이 사용자 화면에 뜨게 됩니다. 그래서 아래처럼 심볼로 객체를 추가해야 합니다. 
const showName = Symbol("show name")
user[showName] = function () {
	console.log(this.name);
};

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

이렇게 하면 다른 개발자가 만든 코드에 영향을 미치지 않고 메소드를 추가할 수 있습니다. 원래 유저에게 이런 이름의 메소드가 있었는지, 다른 사람이 만든 프로퍼티를 덮어쓰지 않는지 걱정할 필요가 없습니다.

profile
Today I Learned

0개의 댓글