๐ฎ Symbol
- ์๋ฐ์คํฌ๋ฆฝํธ์ ES6์์ ๋์ ๋ 7๋ฒ์งธ ๋ฐ์ดํฐ ํ์
- ๋ณ๊ฒฝ ๋ถ๊ฐ๋ฅํ ์์๊ฐ, ๋ค๋ฅธ ๊ฐ๊ณผ ์ค๋ณต๋์ง ์๋ ์ ์ผ๋ฌด์ดํ ๊ฐ
โจ ์์ฑ -> Symbol ํจ์
- ์ฌ๋ฒ๊ฐ์ Symbol ํจ์๋ฅผ ํธ์ถํ์ฌ ์์ฑํด์ผ ํ๋ค.
- ์์ฑ๋ ์ฌ๋ฒ ๊ฐ์ ์ธ๋ถ๋ก ๋ ธ์ถ๋์ง ์์ ํ์ธํ ์ ์๊ณ , ๋ค๋ฅธ ๊ฐ๊ณผ ์ ๋ ์ค๋ณต๋์ง ์๋๋ค.
const firstSymbol = Symbol();
console.log(typeof firstSymbol); // symbol
- ์์ฑ์ ํจ์๋ก ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ๊ฒ์ฒ๋ผ ๋ณด์ด์ง๋ง, ์์ฑ์ ํจ์๋ค๊ณผ ๋ฌ๋ฆฌ new ์ฐ์ฐ์์ ํจ๊ป ํธ์ถํ์ง ์๋๋ค.
new ์ฐ์ฐ์๋ก ์์ฑ๋ ๊ฒ๋ค์ ํธ์ถํ๋ฉด ๊ฐ์ฒด(์ธ์คํด์ค)๊ฐ ์์ฑ๋์ง๋ง, ์ฌ๋ฒ ๊ฐ์ ๋ณ๊ฒฝ ๋ถ๊ฐ๋ฅํ ์์๊ฐ์ด๋ค.
- ์ฌ๋ฒ ํจ์์๋ ์ ํ์ ์ผ๋ก ๋ฌธ์์ด์ ์ธ์๋ก ์ ๋ฌํ ์ ์๋ค.
- ์์ฑ๋ ์ฌ๋ฒ ๊ฐ์ ๋ํ ์ค๋ช ์ผ๋ก ๋๋ฒ๊น ์ฉ๋๋ก๋ง ์ฌ์ฉ๋๋ฉฐ, ์ฌ๋ฒ ๊ฐ ์์ฑ์ ์ด๋ ํ ์ํฅ์ ์ฃผ์ง ์๋๋ค.
- ์ฌ๋ฒ ๊ฐ์ ๋ํ ์ค๋ช ์ด ๊ฐ๋๋ผ๋ ์ฌ๋ฒ ๊ฐ์ ์ ์ผ๋ฌด์ดํ๊ฒ ์์ฑ๋๋ค.
const f_symbol1 = Symbol('first Symbol');
const f_symbol2 = Symbol('first Symbol');
console.log(f_symbol1 === f_symbol2) // false
- ์ฌ๋ฒ ๊ฐ์ ์๋ฌต์ ์ผ๋ก ๋ฌธ์์ด์ด๋ ์ซ์ ํ์ ์ผ๋ก ๋ณํ ๋์ง ์๋๋ค.
- ๋จ, ๋ถ๋ฆฌ์ธ ํ์ ์ผ๋ก๋ ์๋ฌต์ ์ผ๋ก ํ์ ๋ณํ๋๋ค.
const mySymbol = Symbol();
// ๋ฌธ์์ด, ์ซ์ ํ์
์ผ๋ก ๋ณํ๋์ง ์๋๋ค.
// Uncaught TypeError: Cannot convert a Symbol value to a string ...
console.log(mySymbol + '');
console.log(+mySymbol);
// ๋ถ๋ฆฌ์ธ ํ์
์ผ๋ก๋ ๋ณํ๋๋ค.
console.log(!!mySymbol); // true
// if๋ฌธ ๋ฑ์์ ์กด์ฌ ํ์ธ ๊ฐ๋ฅํ๋ค.
if(mySymbol)
console.log('mySymbol is not empty');
- Symbol ํจ์๋ ํธ์ถ๋ ๋๋ง๋ค ์ ์ผ๋ฌด์ดํ ์ฌ๋ฒ ๊ฐ์ ์์ฑํ๋ค.
- ์ด๋ ์ ์ญ ์ฌ๋ฒ ๋ ์ง์คํธ๋ฆฌ์์ ์ฌ๋ฒ ๊ฐ์ ๊ฒ์ํ ์ ์๋ ํค๋ฅผ ์ง์ ํ ์ ์์ผ๋ฏ๋ก ์ ์ญ ์ฌ๋ฒ ๋ ์ง์คํธ๋ฆฌ์ ๋ฑ๋ก๋์ด ๊ด๋ฆฌ๋์ง ์๋๋ค.
- ํ์ง๋ง, Symbol.for ๋ฉ์๋ ์ฌ์ฉํ์ฌ ๊ฐ์ ์์ฑํ๋ฉด ์ ์ญ ์ฌ๋ฒ ๋ ์ง์คํธ๋ฆฌ ํตํด ๊ณต์ ํ ์ ์๋ค.
๐โ๏ธ ์ ์ญ ์ฌ๋ฒ ๋ ์ง์คํธ๋ฆฌ?
- ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ด ๊ด๋ฆฌํ๋ ์ฌ๋ฒ ๊ฐ ์ ์ฅ์
๐ต๏ธ Symbol.for()
- ๊ฒ์์ ์ฑ๊ณตํ๋ฉด ์๋ก์ด ์ฌ๋ฒ ๊ฐ์ ์์ฑํ์ง ์๊ณ ๊ฒ์๋ ์ฌ๋ฒ ๊ฐ์ ๋ฐํํ๋ค.
- ์คํจํ๋ฉด ์๋ก์ด ์ฌ๋ฒ ๊ฐ์ ์์ฑํ์ฌ Symbol.for ๋ฉ์๋์ ์ธ์๋ก ์ ๋ฌ๋ ํค๋ก ์ ์ญ ์ฌ๋ฒ ๋ ์ง์คํธ๋ฆฌ์ ์ ์ฅ ํ, ์์ฑ๋ ์ฌ๋ฒ ๊ฐ ๋ฐํํ๋ค.
// ๊ฒ์์ ์คํจ,
// ์๋ก์ด ์ฌ๋ฒ ๊ฐ์ ์์ฑํ์ฌ Symbol.for ๋ฉ์๋์ ์ธ์๋ก ์ ๋ฌ๋ ํค๋ก ์ ์ญ ์ฌ๋ฒ ๋ ์ง์คํธ๋ฆฌ์ ์ ์ฅ ํ
// , ์์ฑ๋ ์ฌ๋ฒ ๊ฐ ๋ฐํํ๋ค.
const s1 = Symbol.for('mySymbol');
// ๊ฒ์์ ์ฑ๊ณต,
// ํด๋น ์ฌ๋ฒ ๊ฐ์ ๋ฐํํ๋ค.
const s2 = Symbol.for('mySymbol');
console.log(s1 === s2); // true
๐ต๏ธ Symbol.keyFor()
- ์ ์ญ ์ฌ๋ฒ ๋ ์ง์คํธ๋ฆฌ์ ์ ์ฅ๋ ์ฌ๋ฒ ๊ฐ์ ํค๋ฅผ ์ถ์ถํ ์ ์๋ค.
// ์ ์ญ ์ฌ๋ฒ ๋ ์ง์คํธ๋ฆฌ์ mySymbol์ด๋ผ๋ key๋ก ์ ์ฅ๋ ์ฌ๋ฒ ๊ฐ์ด ์์ผ๋ฉด ์๋ก์ด ์ฌ๋ฒ ๊ฐ์ ์์ฑ ํ ๋ฐํํ๋ค.
const s1 = Symbol.for('mySymbol');
// ํค๋ฅผ ์ถ์ถํ ์ ์๋ค.
Symbol.keyFor(s1); // mySymbol
// Symbol ํจ์๋ฅผ ํธ์ถํ์ฌ ์์ฑํ ์ฌ๋ฒ ๊ฐ์ ์ ์ญ ์ฌ๋ฒ ๋ ์ง์คํธ๋ฆฌ์ ๋ฑ๋ก๋์ด ๊ด๋ฆฌ๋์ง ์๊ธฐ ๋๋ฌธ์
const s2 = Symbol('foo');
// ํค๋ฅผ ์ถ์ถ ํ์๋ undefined ๊ฐ์ด ํธ์ถ๋๋ค.
Symbol.keyFor(s2); // undefined
๐ ์ฌ๋ฒ๊ณผ ์์
- ๊ฐ์๋ ํน๋ณํ ์๋ฏธ๊ฐ ์๊ณ ์์ ์ด๋ฆ ์์ฒด์ ์๋ฏธ๊ฐ ์๋ ๊ฒฝ์ฐ
- ์์ ๊ฐ์ ๋ณ๊ฒฝ๋ ์ ์์ผ๋ฉฐ, ๋ค๋ฅธ ๋ณ์ ๊ฐ๊ณผ ์ค๋ณต๋ ์๋ ์๋ค.
- ์ด๋ฌํ ๊ฒฝ์ฐ ์ค๋ณต๋ ๊ฐ๋ฅ์ฑ์ด ์๋ ์ฌ๋ฒ ๊ฐ์ ์ฌ์ฉํ๋ค.
const Direction = {
UP: Symbol('up'),
DOWN: Symbol('down'),
LEFT: Symbol('left'),
RIGHT: Symbol('right')
};
const myDirection = Direction.UP;
if(myDirection === Direction.UP) {
console.log('GOING UP')
}
// GOING UP
๐ ์ฌ๋ฒ๊ณผ ํ๋กํผํฐ ํค
- ์ฌ๋ฒ ๊ฐ์ ํ๋กํผํฐ ํค๋ก ์ฌ์ฉํ๋ ค๋ฉด ํ๋กํผํฐ ํค๋ก ์ฌ์ฉํ ์ฌ๋ฒ ๊ฐ์ ๋๊ดํธ๋ฅผ ์ฌ์ฉํด์ผ ํ๋ค.
- ์ ๊ทผํ ๋๋ ๋๊ดํธ๋ฅผ ์ฌ์ฉํด์ผ ํ๋ค.
- ์ฌ๋ฒ ๊ฐ์ผ๋ก ํ๋กํผํฐ ํค๋ฅผ ๋ง๋ค๋ฉด ๋ค๋ฅธ ํ๋กํผํฐ ํค์ ์ ๋ ์ถฉ๋ํ์ง ์๋๋ค.
const obj = {
// ์์ฑ
[Symbol.for('mySymbol')]: 1
};
obj[Symbol.for('mySymbol')]; // 1
๐ช ์ฌ๋ฒ๊ณผ ํ๋กํผํฐ ์๋
- ์ฌ๋ฒ ๊ฐ์ ํ๋กํผํฐ ํค๋ก ์ฌ์ฉํ์ฌ ์์ฑํ ํ๋กํผํฐ๋ for ...in, Object.keys, Object.getOwnPropertyNames ๋ฉ์๋๋ก ์ฐพ์ ์ ์๋ค.
-> ์ฌ๋ฒ ๊ฐ์ ํ๋กํผํฐ ํค๋ก ์ฌ์ฉํ์ฌ ํ๋กํผํฐ ์์ฑ ์ ์ธ๋ถ์ ๋ ธ์ถํ ํ์๊ฐ ์๋ ํ๋กํผํฐ๋ฅผ ์๋ํ ์ ์๋ค.
- ํ์ง๋ง, ์์ ํ๊ฒ ์จ๊ธธ ์ ์๋ ๊ฒ์ ์๋๊ณ ES6์์ ๋์ ๋ Object.getOwnPropertySymbols ๋ฉ์๋ ์ฌ์ฉํ๋ฉด ์ฐพ์ ์ ์๋ค.
const obj = {
[Symbol('mySymbol')]: 1
};
// getOwnPropertySymbols ๋ฉ์๋๋ ์ธ์๋ก ์ ๋ฌํ ๊ฐ์ฒด์ ์ฌ๋ฒ ํ๋กํผํฐ ํค๋ฅผ ๋ฐฐ์ด๋ก ๋ฐํํ๋ค.
console.log(Object.getOwnPropertySymbols(obj)); // [Symbol(mySymbol)]
// getOwnPropertySymbols ๋ฉ์๋๋ก ์ฌ๋ฒ์ ๊ฐ๋ ์ฐพ์ ์ ์๋ค.
const symbolKey1 = Object.getOwnPropertySymbols(obj)[0];
console.log(obj[symbolKey1]); // 1
์ฐธ์กฐ ๋ฌธํ: ๋ชจ๋์๋ฐ์คํฌ๋ฆฝํธ Deep dive, ์ด์ ๋ชจ ์ , pp.605 ~ 613