for() 함수는 글로벌 Symbol 레지스트리에 {key: value} 형태로 Symbol을 저장합니다. 파라미터()의 문자열이 key가 되고 Symbol()로 생성한 값이 value가 됩니다.
const one = Symbol.for("sports"); console.log(one); // Symbol(sports)
⇒ key : "sports", value : Symbol(sports)
⇒ {"sports":Symbol(sports)}
⇒ Symbol("sports")에서 파라미터가 주석이었던 것과는 차이가 있습니다.
이렇게 for() 함수로 저장되는 key:value는 글로벌 Symbol 레지스트리 오브젝트에 저장되는데 이름의 시맨틱 그대로 전역적으로 공유됩니다. 그렇기에 다른 오브젝트에서도 해당 Symbol을 사용할 수 있습니다.
같은 key가 존재하면 등록된 값을 사용합니다.
const one = Symbol.for("sports"); const two = Symbol.for("sports"); console.log(one === two); console.log(Symbol.for(true)); // true // Symbol(true)
⇒ one의 key 값과 two의 key값이 같으므로 Symbol 값을 생성하지 않고 기존에 만든 one에 설정된 값을 사용합니다.
⇒ Symbol.for(true)에서 true를 1로 변환하지 않고, 문자열로 변환하여 key 값으로 사용합니다.
global symbol 레지스트리 오브젝트에서 Symbol의 key값을 구합니다. 파라미터 값으로 Symbol.for()로 등록한 Symbol을 작성하면 해당 Symbol의 key값이 반환됩니다.
만약, key가 없다면 undefined가 반환됩니다.
const one = Symbol.for("book"); const six = Symbol.keyFor(one); console.log(six); // book
⇒ one에 설정된 Symbol(book)이 value로 등록된 key값을 찾습니다. 그 결과 for로 등록한 "book"을 반환합니다.
Symbol을 생성했던 형태를 문자열로 변환하여 반환합니다.
Symbol 값은 반환되지 않습니다.
Symbol 타입에 +로 문자열을 연결하면 TypeError가 발생합니다.
console.log(Symbol("100").toString()); const sym = Symbol.for("book"); console.log(sym.toString()); try { console.log(Symbol() + "ABC"); } catch { console.log("+로 연결 불가"); }; // Symbol(100) // Symbol(book) // +로 연결 불가
Symbol.prototype.description
Symbol 오브젝트의 주석, 설명을 반환하는 메소드
ES2019부터 지원하는 메소드입니다.
Symbol() 함수의 파라미터를 반환
console.log(Symbol("sports").description); console.log(Symbol.for("book").description); console.log(Symbol.iterator.description); // sports // book // Symbol.iterator
toString()과 차이
console.log(Symbol("book").toString()); console.log(Symbol("").toString()); console.log(Symbol().toString()); // Symbol(book) // Symbol() // Symbol()
console.log(Symbol.for("book").description); console.log(Symbol("book").description); console.log(Symbol("").description); console.log(Symbol().description); // book // book // "" // undefined
⇒ toString() : 작성했던 형태가 문자열로 출력
⇒ description : 파라미터 값이 출력되나 파라미터 미작성시 undefined 반환
보통 toString()이나 valueOf()는 Primitive값을 반환하기위해 사용되는 메소드이며 Symbol에도 valueOf() 메소드는 연결되어 있습니다.
하지만 Symbol의 값을 반환하는게 아닌 Symbol을 생성한 형태를 그대로 반환합니다. Symbol.for() 함수를 통해 만든 것도 작성했던 형태인 value를 반환합니다.
console.log(Symbol("100").valueOf()); console.log(Symbol.for("200").valueOf()); // Symbol(100) // Symbol(200)
기본적으로 Symbol은 [[Enumerable]]이 false이기때문에 for-of를 통해 열거할 때 노출되지 않습니다. 그래서 오브젝트 내에 Symbol을 프로퍼티로 등록하여 변수, 함수를 등록해 사용할 경우 for-of로는 해당 변수, 함수를 열거하여 사용할 수 없습니다.
getOwnPropertySymbols 메소드를 사용하면 Symbol만 배열로 반환합니다. 그래서 반환받은 리스트를 순회하여 오브젝트내의 Symbol 프로퍼티 변수, 함수들도 열거해 사용할 수 있습니다.
const obj = {point: 100}; obj[Symbol("one")] = 200; obj[Symbol.for("two")] = 300; console.log(Object.getOwnPropertyNames(obj)); const list = Object.getOwnPropertySymbols(obj); for (const sym of list){ console.log(`${sym.description}: ${obj[sym]}`); }; // ["point"] // one: 200 // two: 300