Symbol
, ์ ํ์ํ๊ฐ.Symbol
์ด๋ผ๋ ํ์
์ 7๋ฒ์งธ๋ก ES์์ ํ์คํ๋ ํ์
์
๋๋ค.
(๊ฐ๋ ํท๊ฐ๋ฆฌ๋ ๊ฒ์ด ์๋๋ฐ, ๊ทธ๋ ๋ค๊ณ ์๋ฐ์คํฌ๋ฆฝํธ์๋ 7๊ฐ์ ํ์
๋ง ์กด์ฌํ๋ ๊ฒ์ด ์๋๋๋ค. BigInt
๋ผ๋ ํ์
๋ ์กด์ฌํฉ๋๋ค.)
ํ์ง๋ง... ์ค์ ๋ก ํ๋ก์ ํธํ ๋๋ ์๊ฐ๋ณด๋ค ์ฐ์ง๋ ์๋ ํ์
์ด๋ผ ์ ๋์ด๊ฐ๋ ๊ฒ์ด ํ์ค์ธ๋ฐ์.
๊ทธ๋ ์ง๋ง, ํ์คํ๋์๋ค๋ ๊ฒ์ ๋ฌด์ธ๊ฐ๊ฐ ๋ฌธ์ ๋์๋ค๋ ๊ฒ์ด๊ณ , ๋ฐ๋ผ์ ์ด๋ฌํ ๋ฌธ์ ์ ์ ์ธ์งํด์ผ ํ๋ ๊ฒ์ด ์ฐ์ ์
๋๋ค.
๋ฌด์์ด ๋ฌธ์ ์์๊น์?
์ฐ๋ฆฌ๋ ์ฑ
์ ์ญ ํ์ด๋ณด๋ฉฐ, ์ด๋ ํ ์ํ๋๋ผ๋ ๋ณ๊ฒฝ์ด ๋ถ๊ฐ๋ฅํ ์์๋ผ๋ ๊ฒ์ ํ์ธํ์ต๋๋ค.
ํ์ง๋ง, ์์์ ๊ฐ์ ๋ฒ ๋ ์ ์๋ค๋ฉด ์ด๋จ๊น์?
๋ค๋ฅธ ๋ณ์๋ก๋ ํด๋น ๋ณ์๊ฐ ์๋ ๋ก์ง์ ์ ๊ทผํ์ฌ ์ ์ดํ ์ ์๋ค๋ ์๋ฏธ๊ฐ ๋๋ฏ๋ก ์์ ์ฑ์ด ๋จ์ด์ง ์ ์์ต๋๋ค.
const Directions = Object.freeze({
UP: 0,
DOWN: 1,
LEFT: 2,
RIGHT: 3
})
// ์์๋ก, ํ ๋ฒ ๋ค๋ฅธ ๋๊ฒฐ๋ ๊ฐ์ฒด๋ฅผ ํ๋ ๋ ์์ฑํ๋ค.
const Direction = Object.freeze({
UP: 3,
DOWN: 2,
LEFT: 1,
RIGHT: 0
})
// ํ์ฌ `Directions` ๊ฐ์ฒด์ ํค๋ค์ด ์ ์ฅ๋์ด ์๋ค.
const directionArr = Object.keys(Directions);
const moveCallback = (d) => {
// ์ํ๋ ๊ฒฐ๊ณผ ๊ฐ์ด ํด๋นํ๋ ํ๋กํผํฐ ํค๋ฅผ ํ ๋๋ก ์ถ๋ ฅ๋ ๊ฒ์ด๋ค.
console.log(`moved ${directionArr[d]}`);
}
const move = (cb, direction) => {
return moveCallback(direction)
}
// ์ค์๋ก ์ธ์๋ก ๋ค๋ฅธ ๊ฐ์ฒด๋ฅผ ํ ๋นํ๊ณ ,
// ๊ฒฐ๊ณผ์ ์ผ๋ก ๋ก์ง์ ๋์ํ๋ ์ํ๋ ๊ฐ์ด ์ถ๋ ฅ๋์ง ์๋๋ค.
move(moveCallback, Direction.UP) // moved RIGHT
์ฆ, ๋๊ตฌ๋ ์ํ๋ ์์๊ฐ์ ํ๋ด๋ผ ์ ์๊ธฐ์, ์์ ์ฑ์ด ๋จ์ด์ง๋ค๋ ๊ฒ์ด์ง์.
๋ํ, ์ ๊ทผ์ ํ ์ ์๋ค๋ ๊ฒ๋ ๋ฌธ์ ์ ๋๋ค. ํนํ ์ด๋ ๋นํธ์ธ ๊ฐ์ฒด์ ํ๋กํ ํ์ ์ ์๋กญ๊ฒ ๋ง๋ค์์ ๋๊ฐ ๋ฌธ์ ์ง์.
๋์ฒด์ ์ผ๋ก ๋ง์ด ๋ง๋ค์ด ์ฐ๋ sum
์ด ๊ทธ๋ ์ต๋๋ค.
Array.prototype.sum = function () {
return this.reduce((acc, cur) => acc + cur, 0)
}
๋ง์ฝ ์ด๋ฌํ ๋ฉ์๋๊ฐ ์ค์ ๋ก ํ์คํ๋์๋ค๋ฉด ์ด๋ป๊ฒ ๋ ๊น์?
๊ทธ๋ ๋ค๋ฉด ํ์คํ๋ ๋ฉ์๋๊ฐ ์๋์๋์ด, ๊ฒฐ๊ณผ์ ์ผ๋ก ์ด๋ฅผ ๋ชจ๋ฅด๋ ๊ฐ๋ฐ์๋ค๊ณผ์ ์์
์์ ํฐ ํผ๋์ด ์๊ฒ ์ง์? ๐ญ
๋ฐ๋ผ์ ๊ธฐ์กด์ ๊ฐ๋ฐ์๋ค์ ์ด๋ฐ ์๊ฐ์ ํ๊ฒ ๋์์ต๋๋ค.
"์ ๊ทผํ ์๊ฐ ์์ด ์ ๋ ์ถฉ๋ํ ์ ์๋ ์์ ํ ํ์ ๊ฐ์ด ์์๊น"
์ฌ๋ฌ ํ์คํ ๋
ผ์์ ๊ฑธ์ณ, ๊ฒฐ๊ตญ ์ด๋ฌํ ๊ธฐ๋์ ๋ถํฅํ๋ ๊ฐ์ด ํ์ํ์ต๋๋ค. ๊ทธ๊ฒ์ด ๋ฐ๋ก Symbol
์
๋๋ค.
์๊ฐ๋ณด๋ค ๋งค์ฐ ๊ฐ๋จํฉ๋๋ค. ๊ทธ์ Symbol
๊ฐ์ฒด๋ก ์ง์ ๊ฐ์ธ์ฃผ๋ฉด ๋ฉ๋๋ค.
์ด๋, ์ค์ํ ๊ฑด ๊ฐ์ธ์ง ๊ฐ์ string
์ผ๋ก ์๋ฌต์ ํ์
๋ณํ์ด ๋ฐ์ํ๊ฒ ๋ฉ๋๋ค.
const hi = Symbol('hi'); // Symbol(hi)
// ํ์
์ string์ผ๋ก ๋ณํ์ด ๋๋ค.
const test = function() {
console.log('test!')
};
const symbolTest = Symbol(test);
// Symbol(function() {
// console.log('test!')
// })
์ด๋ฌํ ๊ฐ์ ๊ณ ์ ์ ๊ฐ์ผ๋ก, ๋ค๋ฅธ ๋ฌธ์์ด, ํน์ ๋๊ฐ์ ๊ฐ์ ๊ฐ๊ณ ์๋ ์ฌ๋ณผ๋ก๋ ๋น๊ต๊ฐ ๋ถ๊ฐ๋ฅํฉ๋๋ค.
(๋ง์น ์ฃผ์๊ฐ์ ๊ฐ์ง๊ณ ๋น๊ตํ๋ ๊ฒ์ฒ๋ผ ๋ง์ด์ฃ )
const hi = Symbol('hi'); // Symbol(hi)
console.log('hi' === hi) // false;
console.log(Symbol('hi') === hi) // false;
ํน์ฌ๋ ๋ง์ฝ, ๋ด๋ถ์ ๊ฐ์ ๊ฐ์ ธ์ค๊ณ ์ถ๋ค๋ฉด ์ด๋ป๊ฒ ํด์ผ ํ ๊น์?
์ด๋ด ๋๋ Symbol
ํ๋กํ ํ์
๊ฐ์ฒด ์์ ๋ด์ฅ๋ Symbol.prototype.description
๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
console.log(hi.description) // 'hi'
๊ทธ๋ฐ๋ฐ ๋ง์ฝ ์ด๋ฐ ์ฌ๋ณผ ํ์
์ด ์ฌ๋ฌ ๊ณณ์ ์ฐ์ฌํ๋ค๋ฉด, ์ด ์ญ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๊ฒ ์ฃ ?
๋ฐ๋ผ์ ์ด๋ฌํ ์ฌ๋ณผ ๊ฐ์ ์ ์ญ์์ ๊ด๋ฆฌํด์ค ์๋ ์์ต๋๋ค.
์ด๋ฌํ ์ ์ญ ์ฌ๋ณผ ๋ ์ง์คํธ๋ฆฌ์ ๋ฑ๋ก๋ ํค์ ๊ฐ์, ์ผ๋ฐ ์ฌ๋ณผ๋ก๋ ์ ๊ทผ์ด ๋ถ๊ฐ๋ฅํด์.
const hi = Symbol('hi')
// keyFor์ ์ ์ญ ์ฌ๋ณผ ๋ ์ง์คํธ๋ฆฌ์ ๋ฑ๋ก๋ ์ฌ๋ณผ์ ๊ฒ์์ ํ๋ ๋ฉ์๋์
๋๋ค.
// ์ด๋ ์ ๋ฌ๋ฐ๋ ์ธ์๋ ์ค๋ก์ง ์ฌ๋ณผ ํ์
์
๋๋ค.
console.log(Symbol.keyFor(hi)); // undefined
๋ฐ๋ผ์ ์ ์ญ ์ฌ๋ณผ ๋ ์ง์คํธ๋ฆฌ์ ๋ฑ๋กํ๋ ๋ฐฉ๋ฒ์, Symbol.for
์
๋๋ค.
Symbol.for
์ ์ข ํน์ดํ๊ฒ ๋์ํ๋๋ฐ์, ๋ฑ๋ก๊ณผ ๊ฒ์ ๋ชจ๋ ๊ฐ๋ฅํฉ๋๋ค.
์ผ๋จ ๊ฒ์ํด๋ณด๊ณ , ์๋๋ฉด ์ง์ ์๊ธฐ๊ฐ ํค์ ๊ฐ์ ์์ฑํด๋ฒ๋ฆฝ๋๋ค.
๊ทธ๋ฆฌ๊ณ Symbol.keyFor
๋ฉ์๋๋ ์ค์ง ๊ฒ์๋ง ๊ฐ๋ฅํ ๊ธฐ๋ฅ์ ํ์ฃ .
๊ฒ์ ๊ฒฐ๊ณผ๋ ์ฌ๋ฒ ๊ฐ์ ํค์ด๋ฉฐ, ์๋ค๋ฉด undefined
์
๋๋ค.
const s = Symbol.for('hi');
console.log(Symbol.keyFor(s)); // 'hi'
ํ๋กํผํฐ๋ฅผ ์จ๊ธธ ์ ์๊ณ , ์ถฉ๋ํ์ง ์๊ฒ ํ๋ค๋ ์ ์ ์์ ํ๊ฒ ๋ฉ์๋๋ฅผ ๊ด๋ฆฌํ ์
์๋ค๋ ์ฅ์ ์ ์ฃผ๊ฒ ๋์์ต๋๋ค.
const _s = (key) => Symbol.for(key)
Array.prototype[_s('sum')] = function () {
return this.reduce((acc, cur) => acc + cur, 0)
}
console.log([1,2,3,4][_s('sum')]()) // 10
๋ชจ์์ด ์ด์ํ์ง๋ง, ๋ง์ฝ ํด๋น ํ๋กํผํฐ๋ฅผ ํ ๋๋ก ์ข ๋ ์ธ๋ฐํ ์ ๊ทผ์ ํ๋กํผํฐ๋ฅผ ์์ฑํ๋ค๋ฉด ์ด๋จ๊น์? ์ฌ์ฉ์๋ค์๊ฒ๋ ์ ๋๋ก ๋ณด์ด์ง ์์ผ๋ ๋ด๋ถ์ ์ผ๋ก ์ ์ ๊ธฐ๋ฅ์ ํ๊ฒ ๋๊ณ , ์ข ๋ ์์ ํ ์ฝ๋ ๊ด๋ฆฌ๊ฐ ๊ฐ๋ฅํด์ง๋ ์ฅ์ ์ด ์๊น๋๋ค.
์ด ์น๊ตฌ๋ค์ ์ข ๋ฒ์ฉ์ ์ผ๋ก ์ฐ๋ฆฌ๊ฐ ์ฌ์ฉํ๋ ์ฌ๋ณผ๋ค์ด์์.
์ด ์น๊ตฌ๋ค์ ๊ธฐ๋ณธ์ ์ผ๋ก ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ ๋ด๋ถ ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉ๋๋ ์น๊ตฌ๋ค์ธ๋ฐ, ๋ํ์ ์ผ๋ก Symbol.iterator
์ Symbol.search
๊ฐ ์์ต๋๋ค.
์ค์ ๋ก Symbol.iterator
์ ๊ฐ๊ฒ๋ ๊ฐ์ฒด๋ iterable
ํ ์์ฑ์ ๊ฐ์ง ์ ์์ต๋๋ค. ์๋ง ์ด๊ฒ์ด ๊ทผ๊ฐ์ด ๋์ด for ... in ...
๋ฌธ๋ฒ์ ์ฌ์ฉํ ์ ์๊ฒ ๋ ๊ฒ์ด ์๋๊น ์ถ์ธกํ๊ณ ์์ต๋๋ค. (์ด๋ง๋ฌด์ํ์ฃ ?)
๊ฐ์ธ์ ์ผ๋ก ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์ ํ ๋๋ ์ ์ฉํ๊ฒ ์ผ๋ ๊ฒ ๊ฐ์ต๋๋ค.
const iterableObject = {
0: 1,
1: 2,
2: 3,
3: 4,
4: 5,
[Symbol.iterator]() {
let cur = 0;
const max = Object.keys(iterableObject).length;
return {
next() {
return { value: iterableObject[cur++], done: cur > max + 1 };
}
};
}
};
// ์ด์ ๋ ๊ฐ์ฒด ์ํ๋ฅผ ํตํด ๊ฐ์ ์ ๊ทผํ ์ ์๊ตฐ์! ๐ฎ
for (let i of iterableObject) {
console.log(i)
}
// 1
// 2
// 3
// 4
// 5
์ด๋ ๊ฒ ์ดํฐ๋ ์ด์ ํ๋กํ ์ฝ์ ์ฌ๋ณผ๋ก ๊ตฌํํ๋, ์ด์ ๋ ํ๋กํผํฐ ํค๊ฐ ๊ฒน์น๋ ๊ฒ์ ๋ํ ๋๋ ค์์์ ๋ฒ์ด๋๊ฒ ๋์๋ค๋ ์ ์ด, ์ด๋ป๊ฒ ๋ณด๋ฉด ํ์ค์ ๋ง๋ค์ด๋ด๋ ๊ฐ๋ฐ์ ๋ถ๋ค๊ป๋ ๊ฝค๋ ํฐ ์์์ด ๋ ๊ฒ ๊ฐ์์!
Symbol.search
๋ ๋ฌด์์ผ๊น์?์ด ์น๊ตฌ๋ ์ธ๋ฑ์ค ๊ฒ์์ ๊ดํ ๋ฉ์๋๋ฅผ ๋ง๋๋ ๋ฐ ์ฌ์ฉ๋ ์น๊ตฌ์์.
์ค์ ๋ก String.prototype.search
(๋ฌธ์์ด์ด๋ ์ ๊ทํํ์ ํจํด์ ๋ง์ถฐ ์ธ๋ฑ์ค ๊ฒ์์ ๋ฐํํ๋ ์น๊ตฌ)๋ฅผ ์ฌ์ฉํ ๋ ํธ์ถ๋๋ค๊ณ ํ๋ค์!
class SearchStr {
constructor(value) {
this.originalString = value;
this.value = new RegExp(value);
}
[Symbol.search](string) {
const idx = string.search(this.value);
if (idx < 0) return null;
return string.slice(idx, idx + this.originalString.length);
}
}
// search๋ก ํธ์ถ๋ ๋, ํด๋น ์ํ๋ ๋ก์ง์ด ๋ฐํ๋๊ฒ๋ ํ ์ ์์ด์ ๐
console.log('Hello, World!'.search(new SearchStr('Wor'))); // Wor
'์ ๋ด ํ๋ก์ ํธ๋ Symbol
์ ์ฐ์ง ์์์๊น'ํ๋ฉฐ ์ง๋์น ํํ๋ ํ์ง ์์ผ์
๋ ๋ฌด๋ฐฉํฉ๋๋ค.
์ค์ ๋ก๋ MDN์์๋ ํด๋น ํ์
์ ๊ดํ์ฌ ๋ค์๊ณผ ๊ฐ์ด ๋งํฉ๋๋ค.
Symbol
ํ์ ์ ๊ณ ๋๋ก ํนํ๋ ์ฉ๋๋ก ์ฐ์ด๋ฉฐ, ๋ฒ์ฉ์ฑ์ ํ์ ํ ๋จ์ด์ง๋๋ค.
์ฐ๋ฆฌ๊ฐ ์ด๋ฅผ ์ ์ผ๋ค๊ณ ์์ฑ ํ๊ธฐ๋ณด๋ค๋, ์ข ๋ ์ค์ฉ์ ์ผ๋ก ํ๋ก์ ํธ๋ฅผ ํ๋ค๊ณ ์๊ฐํ๋ฉด ํธํ ๊ฒ ๊ฐ์์.
๋ชจ๋ ๊ฐ๋ฐ์ ๋ฆฌ์์ค ์ธ์์ด๋ผ๊ณ ์๊ฐํด์. ๋ฆฌ์์ค ํฌ์ ๋๋น, ์ผ๋ง๋ ์ฐ์ถ์ด ๋๋์ง์ ๋ฐ๋ผ ์ฌ๋์ ๋ฅ๋ ฅ์ด ๊ฒฐ์ ๋๋ค๊ณ ์๊ฐํฉ๋๋ค.
๋ง์ฝ ์์ํ๊ณ ์์ ํ๋ก์ ํธ์ ์ด๋ฌํ ํ์ ์ ์ฌ์ฉํ๋ค๋ฉด, ์ด๋ ์ด์ฉ๋ฉด ๋ฐ๋๋ก ์ ์ก๋ ๊ฒฉ์ผ ์๋ ์์ผ๋ฏ๋ก, ์ฐ๋ฆฌ๋ ํฉ๋ฆฌ์ ์ผ๋ก ๊ฐ๋ฐ์ ํ ๊ฒ์ด๋๋๋ค. ๐
๊ทธ๋ผ, ๋ค๋ค ์ค๋๋ ์ฆ๊ฑฐ์ด ์ฝ๋ฉํ์๊ธธ ๋ฐ๋ผ๋ฉฐ. ์ด์! ๐