자바스크립트는 객체 프로퍼티 키로 문자형, 심볼형만 허용함
'심볼(symbol)'은 유일한 식별자(unique identifier)를 만들고 싶을 때 사용합니다.
Symbol()
을 사용하면 된다.
// id는 새로운 심볼이 됩니다.
let id = Symbol();
// 심볼 id에는 "id"라는 설명이 붙습니다.
let id = Symbol("id");
let id1 = Symbol("id");
let id2 = Symbol("id");
alert(id1 == id2); // false
let id = Symbol("id");
alert(id); // TypeError: Cannot convert a Symbol value to a string
let id = Symbol("id");
alert(id.toString()); // Symbol(id)가 얼럿 창에 출력됨
//symbol.description 프로퍼티를 이용하면 설명만 보여주는 것도 가능
let id = Symbol("id");
alert(id.description); // id
let user = { // 서드파티 코드에서 가져온 객체
name: "John"
};
let id = Symbol("id");
user[id] = 1;
alert( user[id] ); // 심볼을 키로 사용해 데이터에 접근할 수 있습니다.
id: 대신 Symbol('id')을 사용한 이유는
user.id = 로 다른 값으로 의도치않게 덮어씌일 수 있기 때문.
let user = { name: "John" };
// 문자열 "id"를 사용해 식별자를 만들었습니다.
user.id = "스크립트 id 값";
// 만약 제3의 스크립트가 우리 스크립트와 동일하게 문자열 "id"를 이용해 식별자를 만들었다면...
user.id = "제3 스크립트 id 값"
// 의도치 않게 값이 덮어 쓰여서 우리가 만든 식별자는 무의미해집니다.
// ...
let id = Symbol("id");
user[id] = "제3 스크립트 id 값";
//객체의 경우에는 다음과 같이 사용하면된다.
let id = Symbol("id");
let user = {
name: "John",
[id]: 123 // "id": 123은 안됨
};
이렇게 하면 수정을 방지할 수 있다.
let id = Symbol("id");
let user = {
name: "John",
age: 30,
[id]: 123
};
for (let key in user) alert(key);
// name과 age만 출력되고, 심볼은 출력되지 않습니다.
// 심볼로 직접 접근하면 잘 작동합니다.
alert( "직접 접근한 값: " + user[id] );
전역 심볼 레지스트리 안에 심볼을 만들고 해당 심볼에 접근하면, 이름이 같은 경우 항상 동일한 심볼을 반환해준다.
// 전역 레지스트리에서 심볼을 읽습니다.
let id = Symbol.for("id"); // 심볼이 존재하지 않으면 새로운 심볼을 만듭니다.
// 동일한 이름을 이용해 심볼을 다시 읽습니다(좀 더 멀리 떨어진 코드에서도 가능합니다).
let idAgain = Symbol.for("id");
// 두 심볼은 같습니다.
alert( id === idAgain ); // true
전역 심볼을 찾을 때 사용되는 Symbol.for(key)에 반대되는 메서드.
Symbol.keyFor(sym)를 사용하면 이름을 얻을 수 있다.
// 이름을 이용해 심볼을 찾음
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
근데 대부분의 라이브러리나 내장 함수등은 이런 메서드를 사용하지 않는다고한다