인프런 강의 자바스크립트 중급 - 코딩앙마 를 듣고 정리한 내용입니다.
객체 프로퍼티의 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]}.`);
}
이렇게 하면 다른 개발자가 만든 코드에 영향을 미치지 않고 메소드를 추가할 수 있습니다. 원래 유저에게 이런 이름의 메소드가 있었는지, 다른 사람이 만든 프로퍼티를 덮어쓰지 않는지 걱정할 필요가 없습니다.