Language/JavaScript

[JS] ๐Ÿ“š ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ž๋ฃŒํ˜• Symbol ๐Ÿšฉ ์ •๋ฆฌ

์ธํŒŒ_ 2021. 10. 5. 17:24

Symbol

Symbol์ด๋ž€?

1997๋…„ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๊ฐ€ ECMAScript๋กœ ์ฒ˜์Œ ํ‘œ์ค€ํ™”๋œ ์ด๋ž˜๋กœ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” 6๊ฐœ์˜ ํƒ€์ž…์„ ๊ฐ€์ง€๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

 

[์›์‹œ ํƒ€์ž… (primitive data type)]

  • Boolean
  • null
  • undefined
  • Number
  • String

 

[๊ฐ์ฒด ํƒ€์ž… (Object type)]

  • Object

 

์‹ฌ๋ณผ(symbol)์€ ES6์—์„œ ์ƒˆ๋กญ๊ฒŒ ์ถ”๊ฐ€๋œ 7๋ฒˆ์งธ ํƒ€์ž…์œผ๋กœ ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€๋Šฅํ•œ ์›์‹œ ํƒ€์ž…์˜ ๊ฐ’์ž…๋‹ˆ๋‹ค.

์‹ฌ๋ณผ์€ ์ฃผ๋กœ ์ด๋ฆ„์˜ ์ถฉ๋Œ ์œ„ํ—˜์ด ์—†๋Š” ์œ ์ผํ•œ ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ ํ‚ค(property key)๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.


Symbol์˜ ์ƒ์„ฑ

์‹ฌ๋ณผ์€ 3๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • Symbol()
  • Symbol.for()
  • Symbol.iterator

โ€‹

Symbol()

Symbol์€ Symbol() ํ•จ์ˆ˜๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

์ด๋•Œ ์ƒ์„ฑ๋œ Symbol์€ ๊ฐ์ฒด๊ฐ€ ์•„๋‹ˆ๋ผ ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€๋Šฅํ•œ ์›์‹œ ํƒ€์ž…์˜ ๊ฐ’์ž…๋‹ˆ๋‹ค.

Symbol() ํ•จ์ˆ˜๋Š” String, Number, Boolean๊ณผ ๊ฐ™์ด ๋ž˜ํผ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜์™€๋Š” ๋‹ฌ๋ฆฌ new ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

let mySymbol = Symbol();

let mySymbol2 = Symbol("something");
// Symbol()์— ๋ฌธ์ž์—ด์„ ์ค„์ˆ˜ ์žˆ๋Š”๋ฐ ๋ณ„๋‹ค๋ฆ‡ ๋œป์€ ์—†๊ณ  ์ฃผ์„ ๊ฐ™์€ ๊ฐœ๋…์ด๋‹ค. 
// ๋””๋ฒ„๊น…ํ• ๋•Œ ์ด ์‹ฌ๋ณผ์ด ์–ด๋Š ์‹ฌ๋ณผ์ธ์ง€ ๊ตฌ๋ถ„ํ•˜๊ธฐ ํŽธํ•˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•œ ์žฅ์น˜

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

โ€‹์‹ฌ๋ณผ์€ ์œ ์ผ์„ฑ์ด ๋ณด์žฅ๋˜๋Š” ์ž๋ฃŒํ˜•์ด๊ธฐ ๋•Œ๋ฌธ์—, ์„ค๋ช…์ด ๋™์ผํ•œ ์‹ฌ๋ณผ์„ ์—ฌ๋Ÿฌ ๊ฐœ ๋งŒ๋“ค์–ด๋„ ๊ฐ ์‹ฌ๋ณผ๊ฐ’์€ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.

์‹ฌ๋ณผ์— ๋ถ™์ด๋Š” ์„ค๋ช…(์‹ฌ๋ณผ ์ด๋ฆ„)์€ ์–ด๋–ค ๊ฒƒ์—๋„ ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋Š” ์ด๋ฆ„ํ‘œ ์—ญํ• ๋งŒ์„ ํ•ฉ๋‹ˆ๋‹ค.

let id1 = Symbol("id");
let id2 = Symbol("id");

alert(id1 == id2); // false

โ€‹

Symbol.for()

- ์ „์—ญ ์‹ฌ๋ณผ

Symbol() ์€ ๊ณ ์œ ํ•œ ์‹ฌ๋ณผ์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ Symbol.for() ๋Š” ์ „์—ญ์œผ๋กœ ์กด์žฌํ•˜๋Š” global symbol table ์˜ ๋ชฉ๋ก์„ ์ฐธ์กฐํ•ฉ๋‹ˆ๋‹ค.

๋•Œ๋ฌธ์— Symbol.for(token string) ์œผ๋กœ ์ •์˜ํ• ๋•Œ, token string ์œผ๋กœ ์ •์˜ ๋œ ์‹ฌ๋ณผ์ด ์žˆ๋‹ค๋ฉด, ํ•ด๋‹น ์‹ฌ๋ณผ์„ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

// ์ „์—ญ Symbol ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— foo๋ผ๋Š” ํ‚ค๋กœ ์ €์žฅ๋œ Symbol์ด ์—†์œผ๋ฉด ์ƒˆ๋กœ์šด Symbol ์ƒ์„ฑ
const s1 = Symbol.for('foo');

// ์ „์—ญ Symbol ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— foo๋ผ๋Š” ํ‚ค๋กœ ์ €์žฅ๋œ Symbol์ด ์žˆ์œผ๋ฉด ํ•ด๋‹น Symbol์„ ๋ฐ˜ํ™˜
const s2 = Symbol.for('foo');

console.log(s1 === s2); // true

โ€‹

Symbol.keyFor()

Symbol.keyFor ์€ global symbol table ๋กœ๋ถ€ํ„ฐ ์กด์žฌํ•˜๋Š” Symbol์˜ token string ์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

var token = Symbol.for("tokenString");
console.log(Symbol.keyFor(token) === "tokenString"); // true

โ€‹

Symbol.description

Symbol.keyFor๊ฐ€ ์ „์—ญ ์‹ฌ๋ณผ์˜ ์ด๋ฆ„์„ ๋ฐ˜ํ™˜ํ•˜๋ฉด,

์ด๊ฑด ์ผ๋ฐ˜ ์‹ฌ๋ณผ ์ด๋ฆ„์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

const shareSymbol = Symbol.for('myKey');
console.log(Symbol.keyFor(shareSymbol)); // myKey

const unsharedSymbol = Symbol('myKey');
console.log(Symbol.keyFor(unsharedSymbol)); // undefined
console.log(unsharedSymbol.description); // myKey
โ€‹Symbol ํ•จ์ˆ˜๋Š” ๋งค๋ฒˆ ๋‹ค๋ฅธ Symbol ๊ฐ’์„ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์— ๋ฐ˜ํ•ด,
Symbol.for ๋ฉ”์†Œ๋“œ๋Š” ํ•˜๋‚˜์˜ Symbol์„ ์ƒ์„ฑํ•˜์—ฌ ์—ฌ๋Ÿฌ ๋ชจ๋“ˆ์ด ํ‚ค๋ฅผ ํ†ตํ•ด ๊ฐ™์€ Symbol์„ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋‹ค.
Symbol.for ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด ์ƒ์„ฑ๋œ Symbol ๊ฐ’์€ ๋ฐ˜๋“œ์‹œ ํ‚ค๋ฅผ ๊ฐ–๋Š”๋‹ค.
์ด์— ๋ฐ˜ํ•ด Symbol ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ์ƒ์„ฑ๋œ Symbol ๊ฐ’์€ ํ‚ค๊ฐ€ ์—†๋‹ค.

Symbol์˜ ์‚ฌ์šฉ

โ€‹๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ ํ‚ค๋Š” ๋นˆ ๋ฌธ์ž์—ด์„ ํฌํ•จํ•˜๋Š” ๋ชจ๋“  ๋ฌธ์ž์—ด๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

const obj = {};
const v = "name";

obj[v] = 'myProp';
obj[123] = 123; // 123์€ ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜๋œ๋‹ค.
// obj.123 = 123;  // SyntaxError: Unexpected number
obj['prop' + 123] = false;

console.log(obj); 
/* 
{ 
  name : 'myProp', 
  '123' : 123, 
  prop123 : false 
}
*/

Symbol ๊ฐ’๋„ ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ ํ‚ค๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Symbol ๊ฐ’์€ ์œ ์ผํ•œ ๊ฐ’์ด๋ฏ€๋กœ Symbol ๊ฐ’์„ ํ‚ค๋กœ ๊ฐ–๋Š” ํ”„๋กœํผํ‹ฐ๋Š” ๋‹ค๋ฅธ ์–ด๋– ํ•œ ํ”„๋กœํผํ‹ฐ์™€๋„ ์ถฉ๋Œํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

const obj = {};

const mySymbol = Symbol('mySymbol');
const mySymbol2 = Symbol('mySymbol');

obj[mySymbol] = 123;
obj[mySymbol2] = 456;

console.log(obj); // { [Symbol(mySymbol)] : 123, Symbol(mySymbol)] : 456}
console.log(obj[mySymbol]); // 123

โ€‹โ€‹

๐Ÿ’ก ์‹ฌ๋ณผ์€ ๋ฌธ์žํ˜•์œผ๋กœ ์ž๋™ ํ˜• ๋ณ€ํ™˜๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„  ๋ฌธ์žํ˜•์œผ๋กœ์˜ ์•”์‹œ์  ํ˜• ๋ณ€ํ™˜์ด ๋น„๊ต์  ์ž์œ ๋กญ๊ฒŒ ์ผ์–ด๋‚˜๋Š” ํŽธ์ž…๋‹ˆ๋‹ค.

alert ํ•จ์ˆ˜๊ฐ€ ๊ฑฐ์˜ ๋ชจ๋“  ๊ฐ’์„ ์ธ์ž๋กœ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ์ด์œ ๊ฐ€ ์ด ๋•Œ๋ฌธ์ด์ฃ .

โ€‹๊ทธ๋Ÿฌ๋‚˜ ์‹ฌ๋ณผ์€ ์˜ˆ์™ธ์ž…๋‹ˆ๋‹ค.

์‹ฌ๋ณผํ˜• ๊ฐ’์€ ๋‹ค๋ฅธ ์ž๋ฃŒํ˜•์œผ๋กœ ์•”์‹œ์  ํ˜• ๋ณ€ํ™˜(์ž๋™ ํ˜• ๋ณ€ํ™˜)๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์•„๋ž˜ ์˜ˆ์‹œ์—์„œ alert๋Š” ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.

let id = Symbol("id"); 
alert(id); // TypeError: Cannot convert a Symbol value to a string

๋ฌธ์ž์—ด๊ณผ ์‹ฌ๋ณผ์€ ๊ทผ๋ณธ์ด ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ์šฐ์—ฐํžˆ๋ผ๋„ ์„œ๋กœ์˜ ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜๋ผ์„  ์•ˆ ๋ฉ๋‹ˆ๋‹ค.

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„  '์–ธ์–ด ์ฐจ์›์˜ ๋ณดํ˜ธ์žฅ์น˜(language guard)'๋ฅผ ๋งˆ๋ จํ•ด ์‹ฌ๋ณผํ˜•์ด ๋‹ค๋ฅธ ํ˜•์œผ๋กœ ๋ณ€ํ™˜๋˜์ง€ ์•Š๊ฒŒ ๋ง‰์•„์ค๋‹ˆ๋‹ค.

์‹ฌ๋ณผ์„ ๋ฐ˜๋“œ์‹œ ์ถœ๋ ฅํ•ด์ค˜์•ผ ํ•˜๋Š” ์ƒํ™ฉ์ด๋ผ๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด .toString() ๋ฉ”์„œ๋“œ๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ํ˜ธ์ถœํ•ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

let id = Symbol("id");
alert(id.toString()); // Symbol(id)๊ฐ€ ์–ผ๋Ÿฟ ์ฐฝ์— ์ถœ๋ ฅ๋จ

symbol.description ํ”„๋กœํผํ‹ฐ๋ฅผ ์ด์šฉํ•˜๋ฉด ์„ค๋ช…๋งŒ ๋ณด์—ฌ์ฃผ๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

let id = Symbol("id");
alert(id.description); // id

Symbol ์‹ค๋ฌด

class Counter {
  count = 0;

  add() {
    return this.count++;
  }
  get() {
    return this.count;
  }
}

class BetterCounter extends Counter {
  count = function() { ... }; // conflict !!!!!!!!!!!!!!!!!
  ...
}

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ์ฒด์˜ ๋‚ด๋ถ€ ํ•„๋“œ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ชจ๋‘ public์ž…๋‹ˆ๋‹ค.

๊ทธ ๋ง์€ ๋ˆ„๊ตฌ๋“  ๋‚ด๋ถ€ ํ•จ์ˆ˜, ๊ฐ’์„ ๋ฎ์–ด ์“ธ ์ˆ˜ ์žˆ๋‹ค๋Š” ๋ง์ด์ฃ .

โ€‹

์œ„ ์ฝ”๋“œ์—์„ , ๊ทธ๋ƒฅ count๋ผ๋Š” ๋ฌธ์ž์—ด ํ‚ค ๊ฐ’์„ ์‚ฌ์šฉํ•˜๋Š”๋ฐ, ์ด๊ฑฐ๋ฅผ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ์™ธ๋ถ€์— ๋ฐฐํฌ๋ฅผ ํ•œ ๋ฒˆ ํ–ˆ๋‹ค๊ณ  ์ƒ์ƒ์„ ํ•ด๋ณด์„ธ์š”.

๊ทธ๋ฆฌ๊ณ  ๋‹ค๋ฅธ ์–ด๋–ค ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์ด Counter ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋ฐ›์•„์„œ ์ƒ์†์„ ํ†ตํ•ด ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•ด์„œ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ• ๋•Œ, ๋ณดํ†ต ๋‚ด๋ถ€ ์ฝ”๋“œ๊ฐ€ ์–ด๋–ป๊ฒŒ ๋˜์–ด์žˆ๋Š”์ง€ ๋ชจ๋ฅด๊ธฐ๋•Œ๋ฌธ์— ๊ทธ ํ”„๋กœ๊ทธ๋ž˜๋จธ๋Š” ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋‚ด๋ถ€ ๋ณ€์ˆ˜๋ฅผ ํ•˜๋‚˜ ์„ ์–ธํ•˜๋Š”๋ฐ ์ด๋ฆ„์„ count๋ผ๊ณ  ์ง€์—ˆ๋‹ค๊ณ  ์ƒ์ƒํ•ด ๋ด…์‹œ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ๋Œ๋ ค๋ณด๋Š”๋ฐ ๋™์ž‘์ด ์ž˜ ์•ˆ๋  ๊ฒ๋‹ˆ๋‹ค.

๋กœ์ง์ƒ ๋ฌธ์ œ๊ฐ€ ๋ ๊ฒƒ์€ ์—†๋Š”๋ฐ ๋ฌธ์ œ๊ฐ€ ๋˜๋Š” ์ด์œ ๋Š”, ๋ถ€๋ชจํด๋ž˜์Šค ์ธ์Šคํ„ด์Šค count๋ณ€์ˆ˜๊ฐ€ ๋ฎ์–ด์”Œ์›Œ์ ธ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด์ฃ .

โ€‹

๋”ฐ๋ผ์„œ, ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ์˜ˆ๋ฐฉ ํ•˜๊ธฐ ์œ„ํ•ด, Symbol์„ ์จ์„œ '์ˆจ๊น€ ์ฒ˜๋ฆฌ'๋ฅผ ํ•ด์ฃผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์‹ฌ๋ณผ์„ ์ด์šฉํ•ด์„œ ๋‚ด๋ถ€ ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ–ˆ๋‹ค๋ฉด ์ค‘๋ณต๋˜๋Š” ๊ฑฑ์ •์„ ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

โ€‹

์‹ฌ๋ณผ์„ ์„ ์–ธํ•˜๋Š” ์ˆœ๊ฐ„ ์ด๊ฑด private ํ•„๋“œ๋ผ๊ณ  ํ”„๋กœ๊ทธ๋ž˜๋จธ์—๊ฒŒ ๊ฐ€๋…์„ฑ์„ ๋†’์—ฌ์ค„ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ์ธ์Šคํ„ด์Šค ์ค‘๋ณต์„ ํ”ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

const count = Symbol();

class Counter {
  [count] = 0;
  
  add(){
    this[count] += 1;
    return this;
  }
  
  get(){
    return this[count];
  }
}

const counter = new Counter();
console.log(counter.get()); // 0

counter.add().add().add();
console.log(counter.get()); // 3

Symbol.iterator

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

Symbol.iterator๋ฅผ ํ”„๋กœํผํ‹ฐ key๋กœ ์‚ฌ์šฉํ•˜์—ฌ ๋ฉ”์†Œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ  ์žˆ๋Š” ๋นŒํŠธ์ธ ๊ฐ์ฒด(๋นŒํŠธ์ธ ์ดํ„ฐ๋Ÿฌ๋ธ”)๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์•„๋ž˜์˜ ๊ฐ์ฒด๋“ค์€ ์ดํ„ฐ๋ ˆ์ด์…˜ ํ”„๋กœํ† ์ฝœ์„ ์ค€์ˆ˜ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ์ดํ„ฐ๋ ˆ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

์ดํ„ฐ๋ ˆ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค๋Š” ๋œป์€, for of๋ฌธ์œผ๋กœ ์š”์†Œ ํ•˜๋‚˜์”ฉ ์ˆœํšŒ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๋ง์„ ๋œปํ•ฉ๋‹ˆ๋‹ค.

Array

Array.prototype[Symbol.iterator]

โ€‹

String

String.prototype[Symbol.iterator]

โ€‹

Map

Map.prototype[Symbol.iterator]

โ€‹

Set

Set.prototype[Symbol.iterator]

โ€‹

DOM data structures

NodeList.prototype[Symbol.iterator] HTMLCollection.prototype[Symbol.iterator]

โ€‹

arguments

arguments[Symbol.iterator]

// ์ดํ„ฐ๋Ÿฌ๋ธ”
// Symbol.iterator๋ฅผ ํ”„๋กœํผํ‹ฐ key๋กœ ์‚ฌ์šฉํ•œ ๋ฉ”์†Œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜์—ฌ์•ผ ํ•œ๋‹ค.
// ๋ฐฐ์—ด์—๋Š” Array.prototype[Symbol.iterator] ๋ฉ”์†Œ๋“œ๊ฐ€ ๊ตฌํ˜„๋˜์–ด ์žˆ๋‹ค.
const iterable = ['a', 'b', 'c'];

// ์ดํ„ฐ๋ ˆ์ดํ„ฐ
// ์ดํ„ฐ๋Ÿฌ๋ธ”์˜ Symbol.iterator๋ฅผ ํ”„๋กœํผํ‹ฐ key๋กœ ์‚ฌ์šฉํ•œ ๋ฉ”์†Œ๋“œ๋Š” ์ดํ„ฐ๋ ˆ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
const iterator = iterable[Symbol.iterator]();

// ์ดํ„ฐ๋ ˆ์ดํ„ฐ๋Š” ์ˆœํšŒ ๊ฐ€๋Šฅํ•œ ์ž๋ฃŒ ๊ตฌ์กฐ์ธ ์ดํ„ฐ๋Ÿฌ๋ธ”์˜ ์š”์†Œ๋ฅผ ํƒ์ƒ‰ํ•˜๊ธฐ ์œ„ํ•œ ํฌ์ธํ„ฐ๋กœ์„œ 
// value, done ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ–๋Š” ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” next() ํ•จ์ˆ˜๋ฅผ ๋ฉ”์†Œ๋“œ๋กœ ๊ฐ–๋Š” ๊ฐ์ฒด์ด๋‹ค. 
// ์ดํ„ฐ๋ ˆ์ดํ„ฐ์˜ next() ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด ์ดํ„ฐ๋Ÿฌ๋ธ” ๊ฐ์ฒด๋ฅผ ์ˆœํšŒํ•  ์ˆ˜ ์žˆ๋‹ค.
console.log(iterator.next()); // { value: 'a', done: false }
console.log(iterator.next()); // { value: 'b', done: false }
console.log(iterator.next()); // { value: 'c', done: false }
console.log(iterator.next()); // { value: undefined, done: true }

Symbol ์œ ์˜์ 

๊ฐ์ฒด์˜ key๊ฐ€ Symbol์ผ ๊ฒฝ์šฐ, for..in ๋ฐ˜๋ณต๋ฌธ์—์„œ๋Š” ๋ฐฐ์ œ๋œ๋‹ค.

Object.keys ๋ฅผ ์‚ฌ์šฉํ•ด๋„ ํ‚ค๊ฐ€ ์‹ฌ๋ณผ์ธ ํ”„๋กœํผํ‹ฐ๋Š” ๋ฐฐ์ œ๋œ๋‹ค.

๋‹น์—ฐํžˆ ์ˆจ๊น€ ์ฒ˜๋ฆฌ ๊ธฐ๋Šฅ ํ•˜๋Š” ์ž๋ฃŒํ˜• ์ด๋‹ˆ๊นŒ

โ€‹

'์‹ฌ๋ณผํ‰ ํ”„๋กœํผํ‹ฐ ์ˆจ๊ธฐ๊ธฐ(hiding symbolic property) ์›์น™'

์™ธ๋ถ€ ์Šคํฌ๋ฆฝํŠธ๋‚˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” Symbolํ˜• ํ‚ค๋ฅผ ๊ฐ€์ง„ ํ”„๋กœํผํ‹ฐ์— ์ ‘๊ทผ ํ•˜์ง€ ๋ชปํ•จ

Object.assign์€ ์˜ˆ์™ธ?

Symbol ํ‚ค๋ฅผ ๊ฐ€์ง„ ํ”„๋กœํผํ‹ฐ๋„ ๋ณต์‚ฌํ•œ๋‹ค.


# Reference

https://poiemaweb.com/es6-symbol

https://ko.javascript.info/symbol

https://pks2974.medium.com/javascript%EC%99%80-%EC%8B%AC%EB%B3%BC-symbol-bbdf3251aa28