[JS๐Ÿฃ] Symbol ์ž๋ฃŒํ˜•

๊น€๋‹ค์Šฌยท2021๋…„ 9์›” 19์ผ
0

Java Script ์™„์ „ ์ •๋ณต

๋ชฉ๋ก ๋ณด๊ธฐ
5/5
post-thumbnail

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๋ฐ์ดํ„ฐ ํƒ€์ž…

๋ฌธ์ž์—ด, ์ˆซ์ž, ๋ถˆ๋ฆฌ์–ธ, undefined, null, ๊ฐ์ฒด


Symbol ์ด๋ž€?

  • ES6์— ์ถ”๊ฐ€๋œ 7๋ฒˆ์งธ ํƒ€์ž…
  • ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€๋Šฅํ•œ ์›์‹œ ํƒ€์ž…์˜ ๊ฐ’
  • ์ด๋ฆ„์ด ์ถฉ๋Œํ•  ์œ„ํ—˜์ด ์—†๋Š” ๊ฐ์ฒด์˜ ์œ ์ผํ•œ ํ”„๋กœํผํ‹ฐ ํ‚ค๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ

Symbol ๊ฐ’์˜ ์ƒ์„ฑ๊ณผ ํŠน์ง•


1. ์‹ฌ๋ณผ ๊ฐ’์€ Symbol ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ƒ์„ฑ ๊ฐ€๋Šฅ

// ๋‹ค๋ฅธ ํƒ€์ž…์˜ ๊ฐ’์€ ๋ฆฌํ„ฐ๋Ÿด ํ‘œ๊ธฐ๋ฒ•์„ ํ†ตํ•ด ๊ฐ’ ์ƒ์„ฑ ๊ฐ€๋Šฅ
const myString = 'Hello';
const mySymbol = Symbol();

console.log(typeof mySymbol); // symbol
console.log(mySymbol); // Symbol()

2. ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ ํƒ€์ž…์˜ ๊ฒฝ์šฐ new ์—ฐ์‚ฐ์ž๋ฅผ ์ด์šฉํ•ด ๋ž˜ํผ ๊ฐ์ฒด๋กœ์˜ ๋ณ€ํ™˜์ด ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, symbol์€ ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€๋Šฅํ•œ ์›์‹œ ๊ฐ’์ด๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉ ๋ถˆ๊ฐ€๋Šฅ

const strObj = new String('Hello');
const symObj = new Symbol(); // TypeError: Symbol is not a constructor
console.log(strObj); // [String: 'Hello']

3. Symbol ํ•จ์ˆ˜์—๋Š” ์„ ํƒ์ ์œผ๋กœ ๋ฌธ์ž์—ด ์ธ์ˆ˜ ์ „๋‹ฌ ๊ฐ€๋Šฅ

  • ์ƒ์„ฑ๋œ Symbol ๊ฐ’์— ๋Œ€ํ•œ ์„ค๋ช…์ผ ๋ฟ ๊ฐ’ ์ƒ์„ฑ์—๋Š” ์–ด๋– ํ•œ ์˜ํ–ฅ๋„ ์ฃผ์ง€ ์•Š์Œ
  • ์ฆ‰, ์„ค๋ช…์ด ๋™์ผํ•œ ์‹ฌ๋ณผ์„ ์—ฌ๋Ÿฌ๊ฐœ ๋งŒ๋“ค์–ด๋„ ๊ฐ๊ฐ์˜ ์‹ฌ๋ณผ ๊ฐ’์€ ๋‹ค๋ฅด๋‹ค
const mySymbol1 = Symbol('mySymbol');
const mySymbol2 = Symbol('mySymbol');

console.log(mySymbol1.description === mySymbol2.description); // true
console.log(mySymbol1 === mySymbol2); // false

4. ์‹ฌ๋ณผ ๊ฐ’์€ ๋ฌธ์ž์—ด์ด๋‚˜ ์ˆซ์ž ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜๋˜์ง€์•Š์œผ๋‚˜ ๋ถˆ๋ฆฌ์–ธ ํƒ€์ž…์œผ๋กœ๋Š” ๋ณ€ํ™˜๋œ๋‹ค

const mySymbol = Symbol();

// TypeError: Cannot convert a Symbol value to a string
console.log(mySymbol + 'Hello!');
//TypeError: Cannot convert a Symbol value to a number
console.log(mySymbol + 5);

if (mySymbol) {
  console.log('mySymbol์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.'); // mySymbol์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.
}

'์ˆจ๊น€' ํ”„๋กœํผํ‹ฐ๋กœ์„œ ์‚ฌ์šฉ

'์ˆจ๊น€' ํ”„๋กœํผํ‹ฐ๋ž€?

  • ์™ธ๋ถ€ ์ฝ”๋“œ์—์„œ ์ ‘๊ทผ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๊ณ  ๊ฐ’๋„ ๋ฎ์–ด์“ธ ์ˆ˜ ์—†๋Š” ํ”„๋กœํผํ‹ฐ

์ƒํ™ฉ ๊ฐ€์ •

  1. target, A, B ๋ผ๋Š” 3๊ฐœ์˜ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์กด์žฌํ•œ๋‹ค.
  2. target์ด๋ผ๋Š” ์Šคํฌ๋ฆฝํŠธ๊ฐ€ user ๊ฐ์ฒด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.
  3. A, B ์Šคํฌ๋ฆฝํŠธ์—์„œ๋Š” ๊ฐ์ž ์„œ๋กœ์˜ ์ฝ”๋“œ๋ฅผ ๋ชจ๋ฅธ ์ฑ„ ์‹๋ณ„์ž๋ฅผ ์ด์šฉํ•ด user๋ฅผ ์‹๋ณ„ํ•ด์•ผํ•˜๋Š” ์ƒํ™ฉ์ด๋‹ค.

๋ฌธ์ž์—ด id๋ฅผ ์ด์šฉํ•ด ์‹๋ณ„์ž๋ฅผ ๋งŒ๋“ ๋‹ค๋ฉด?

let user = {
  name: 'daseul',
};

user.id = 'A ์Šคํฌ๋ฆฝํŠธ์˜ id ๊ฐ’';
user.id = 'B ์Šคํฌ๋ฆฝํŠธ์˜ id ๊ฐ’ ';

console.log(user); // { name: 'daseul', id: 'B ์Šคํฌ๋ฆฝํŠธ์˜ id ๊ฐ’ ' }
// ์Šคํฌ๋ฆฝํŠธ A์—์„œ ๋งŒ๋“  ์‹๋ณ„์ž๋Š” ๋ฌด์˜๋ฏธํ•ด์ง„๋‹ค.

์‹ฌ๋ณผ์„ ์ด์šฉํ•ด ์‹๋ณ„์ž๋ฅผ ๋งŒ๋“ ๋‹ค๋ฉด?

let user = {
  name: 'daseul',
};

user[Symbol('id')] = 'A ์Šคํฌ๋ฆฝํŠธ์˜ id';
user[Symbol('id')] = 'B ์Šคํฌ๋ฆฝํŠธ์˜ id';

console.log(user); 
/* {
  name: 'daseul',
  [Symbol(id)]: 'A ์Šคํฌ๋ฆฝํŠธ์˜ id',
  [Symbol(id)]: 'B ์Šคํฌ๋ฆฝํŠธ์˜ id'
} */

์‹ฌ๋ณผ์€ for..in๋ฌธ, Object.keys ๋ฉ”์„œ๋“œ์—์„œ ๋ฐฐ์ œ๋œ๋‹ค

for (let key in user) {
  console.log(key); // name
}

console.log(Object.keys(user)); // ['name']

๋”ฐ๋ผ์„œ ์‹ฌ๋ณผ์„ ์ด์šฉํ•˜๋ฉด target ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋ชจ๋ฅด๊ฒŒ user์— ์‹๋ณ„์ž๋ฅผ ๋ถ€์—ฌ ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๊ฐ™์€ ํ‚ค๋ฅผ ์‚ฌ์šฉํ•˜์˜€์„ ๋•Œ ๊ฐ’์ด ๋ฎ์–ด์”Œ์–ด์ง€๋Š” ์ƒํ™ฉ๋„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.


์ „์—ญ ์‹ฌ๋ณผ

  • ์ด๋ฆ„์ด ๊ฐ™์€ ์‹ฌ๋ณผ์ด ๊ฐ™์€ ๊ฐœ์ฒด๋ฅผ ๊ฐ€๋ฅดํ‚ค๊ธธ ์›ํ•˜๋Š” ๊ฒฝ์šฐ
  • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ณณ๊ณณ์—์„œ ์‹ฌ๋ณผ "id"๋ฅผ ์ด์šฉํ•ด ํŠน์ • ํ”„๋กœํผํ‹ฐ์— ์ ‘๊ทผํ•ด์•ผํ•˜๋Š” ์ƒํ™ฉ์ผ ๊ฒฝ์šฐ

Symbol.for / Symbol.keyFor ๋ฉ”์„œ๋“œ


Symbol.for ๋ฉ”์„œ๋“œ

  • ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋ฐ›์€ ๋ฌธ์ž์—ด์„ ํ‚ค๋กœ ์‚ฌ์šฉํ•˜์—ฌ ํ‚ค์™€ ์‹ฌ๋ฒŒ ๊ฐ’์˜ ์Œ๋“ค์ด ์ €์žฅ๋˜์–ด ์žˆ๋Š” ์ „์—ญ ์‹ฌ๋ฒŒ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์—์„œ ํ•ด๋‹น ํ‚ค์™€ ์ผ์น˜ํ•˜๋Š” ์‹ฌ๋ฒŒ ๊ฐ’์„ ๊ฒ€์ƒ‰
    • ๊ฒ€์ƒ‰์— ์„ฑ๊ณตํ•˜๋ฉด ์ƒˆ๋กœ์šด ์‹ฌ๋ฒŒ ๊ฐ’์„ ์ƒ์„ฑํ•˜์ง€ ์•Š๊ณ  ๊ฒ€์ƒ‰๋œ ์‹ฌ๋ฒŒ ๊ฐ’์„ ๋ฐ˜ํ™˜
    • ๊ฒ€์ƒ‰์— ์‹คํŒจํ•˜๋ฉด ์ƒˆ๋กœ์šด ์‹ฌ๋ฒŒ ๊ฐ’์„ ์ƒ์„ฑํ•˜์—ฌ ํ•ด๋‹น ํ‚ค๋กœ ์ „์—ญ ์‹ฌ๋ฒŒ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— ์ €์žฅ ํ›„ ์ƒ์„ฑ๋œ ์‹ฌ๋ฒŒ ๊ฐ’์„ ๋ฐ˜ํ™˜
const globalSym = Symbol.for('id');
const sym = Symbol.for('id');
console.log(globalSym === sym); // true
const globalSym = Symbol.for('id');
const sym = Symbol('id');
console.log(globalSym === sym); // false

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ „์—ญ์—์„œ ์ค‘๋ณต๋˜์ง€ ์•Š๋Š” ์œ ์ผ๋ฌด์ดํ•œ ์ƒ์ˆ˜์ธ ์‹ฌ๋ณผ ๊ฐ’์„ ๋‹จํ•˜๋‚˜๋งŒ ์ƒ์„ฑํ•˜์—ฌ, ์ „์—ญ ์‹ฌ๋ฒŒ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ๋ฅผ ํ†ตํ•ด ๊ณต์œ  ๊ฐ€๋Šฅ


Symbol.keyFor ๋ฉ”์„œ๋“œ

  • ์ „์—ญ ์‹ฌ๋ณผ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— ์ €์žฅ๋œ ์‹ฌ๋ณผ ๊ฐ’์˜ ํ‚ค๋ฅผ ์ถ”์ถœ ๊ฐ€๋Šฅ
const globalSym = Symbol.for('id');
const sym = Symbol('id');

const globalSymKey = Symbol.keyFor(globalSym);
console.log(globalSymKey); // id

const symKey = Symbol.keyFor(sym);
console.log(symKey); // undefined

๋งŒ์•ฝ ์ „์—ญ ์‹ฌ๋ณผ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— ์ €์žฅ๋˜์–ด์žˆ์ง€ ์•Š์€ ์‹ฌ๋ฒŒ ๊ฐ’์„ ์ฐพ๊ณ  ์‹ถ๋‹ค๋ฉด?

  • Object.getOwnPropertySymbols() ๋ฉ”์„œ๋“œ ์‚ฌ์šฉ (ES6 ๋„์ž…)
const obj = {
  [Symbol.for('name')]: 'daseul',
  [Symbol('id')]: 1,
};

console.log(obj[Symbol.for('name')]); // daseul
console.log(obj[Symbol('id')]); // undefined

console.log(Object.getOwnPropertySymbols(obj)); 
// [ Symbol(name), Symbol(id) ]

const symbolValue = Object.getOwnPropertySymbols(obj)[1];

console.log(obj[symbolValue]); // 1

Well-known Symbol

  • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๊ธฐ๋ณธ ์ œ๊ณตํ•˜๋Š” ๋นŒํŠธ์ธ ์‹ฌ๋ฒŒ ๊ฐ’
  • Symbol ํ•จ์ˆ˜ ํ”„๋กœํผํ‹ฐ์— ํ• ๋‹น๋˜์–ด ์žˆ๋‹ค

array, string, map, set ๋“ฑ๊ณผ ๊ฐ™์€ ์ˆœํšŒ๊ฐ€๋Šฅํ•œ ์ดํ„ฐ๋Ÿฌ๋ธ”

  • Symbol.iterator๋ฅผ ํ‚ค๋กœ ๊ฐ–๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง€๋ฉฐ, ์ด ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์ดํ„ฐ๋ ˆ์ดํ„ฐ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ๊ทœ์ •๋˜์–ด์žˆ๋‹ค.
  • Symbol.iterator๋ผ๋Š” Symbol ํƒ€์ž… ๊ฐ’์œผ๋กœ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ์†์„ฑ์ด ์กด์žฌํ•˜๊ณ  ๊ทธ ์†์„ฑ์˜ ๊ฐ’์€ ํ•จ์ˆ˜, ๊ทธ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์ดํ„ฐ๋ ˆ์ดํ„ฐ๊ฐ€ ๋ฐ˜ํ™˜๋˜๋Š” ๊ฒƒ

์ดํ„ฐ๋ ˆ์ดํ„ฐ ๊ฐ์ฒด

  • Iterator๋Š”ย next๋ผ๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ๊ฐ–์Šต๋‹ˆ๋‹ค.
  • nextย ๋ฉ”์†Œ๋“œ๋Š” ๋‹ค์Œ ๋‘ ์†์„ฑ์„ ๊ฐ–๋Š” ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
    • doneย - ๋ฐ˜๋ณต์ด ๋ชจ๋‘ ๋๋‚ฌ๋Š”์ง€๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.
    • valueย - ํ˜„์žฌ ์ˆœ์„œ์˜ ๊ฐ’์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.
const iterable = {
  [Symbol.iterator]() {
    let cur = 1;
    const max = 5;
    return {
      next() {
        return { value: cur++, done: cur > max + 1 };
      },
    };
  },
};

const iter = iterable[Symbol.iterator]();
const it2 = iter.next();
const it3 = iter.next();
console.log(iter); // { next: [Function: next] }
console.log(it2); // { value: 1, done: false }
console.log(it3); // { value: 2, done: false }

์ดํ„ฐ๋ ˆ์ด์…˜ ํ”„๋กœํ† ์ฝœ์„ ์‚ฌ์šฉํ•˜๊ธฐ์œ„ํ•ด ์ผ๋ฐ˜ ๊ฐ์ฒด์— ์ถ”๊ฐ€ํ•ด์•ผํ•˜๋Š” ๋ฉ”์„œ๋“œ ํ‚ค Symbol.iterator๋Š” ๊ธฐ์กด ํ”„๋กœํผํ‹ฐ ํ‚ค ๋˜๋Š” ๋ฏธ๋ž˜์— ์ถ”๊ฐ€๋  ํ‚ค์™€ ์ ˆ๋Œ€๋กœ ์ค‘๋ณต๋˜์ง€ ์•Š์„ ๊ฒƒ์ด๋‹ค.

Symbol์€ ๊ธฐ์กด์— ์ž‘์„ฑ๋œ ์ฝ”๋“œ์— ์˜ํ–ฅ์„ ์ฃผ์ง€์•Š๊ณ  ์ƒˆ๋กœ์šด ํ”„๋กœํผํ‹ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด ๋„์ž…๋˜์—ˆ๋‹ค.


์ฐธ๊ณ  ์‚ฌ์ดํŠธ

profile
์ธ์ƒ์€ ์šฉ๊ธฐ์˜ ์–‘์— ๋”ฐ๋ผ ์ค„์–ด๋“ค๊ฑฐ๋‚˜, ๋Š˜์–ด๋‚œ๋‹ค

0๊ฐœ์˜ ๋Œ“๊ธ€