avatar
Published on

Javascript Symbol

Author
  • avatar
    Name
    yceffort

Javascript Primitive

๊ธฐ์กด์— ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” 6๊ฐ€์ง€์˜ primitive๊ฐ€ ์žˆ์—ˆ๋‹ค.

  • Object
  • string
  • number
  • boolean
  • null
  • undefined

๊ทธ๋Ÿฌ๋‚˜ es6๊ฐ€ ๋“ค์–ด์„œ๋ฉด์„œ symbol์ด๋ผ๋Š” 7๋ฒˆ์งธ primitive๊ฐ€ ์ถ”๊ฐ€๋˜์—ˆ๋‹ค.

Symbol

const helloSymbol = Symbol()
const hiSymbol = Symbol()

์ƒˆ๋กœ์šด ์‹ฌ๋ณผ ๊ฐ’์„ ์ƒ์„ฑํ–ˆ๋‹ค. ์ด ์‹ฌ๋ณผ๋กœ ์ƒ์„ฑํ•œ ๊ฐ’์€ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ const์— ํ• ๋‹น์—๋„ ์ƒ๊ด€์—†๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด๋ ‡๊ฒŒ ์ƒ์„ฑ๋œ ์‹ฌ๋ณผ ๊ฐ’์€ ํ”„๋กœ๊ทธ๋žจ ๋‚ด์—์„œ ์œ ์ผํ•จ์„ ๋ณด์žฅํ•ด ์ค€๋‹ค.

let obj = {}
obj[helloSymbol] = 'hello'
obj[hiSymbol] = 'hi'
console.log(obj)
{Symbol(): "hello", Symbol(): "hi"}

๋ฌผ๋ก  ๋ฌธ์ž์—ด์ด๋‚˜ ์ˆซ์ž๋ฅผ key๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, symbol์€ ์œ ์ผํ•จ์„ ๋ณด์žฅํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ ‡๊ฒŒ ํ‚ค๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

const welcomeSymbol = Symbol('ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค')
console.log(welcomeSymbol)
Symbol(ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค)

Symbol์•ˆ์— ์žˆ๋Š” ๋ฌธ์ž์—ด์€ ์ผ์ข…์˜ ์ฃผ์„์œผ๋กœ ๋ณด๋ฉด ๋  ๊ฒƒ ๊ฐ™๋‹ค.

์˜ˆ์ œ

const isBlocked = Symbol('is blocked element?')

if (element[isBlocked]) {
  openElement(element)
} else {
  element[isBlocked] = true
}

element๋Š” isBlocked๋ผ๋Š” ์‹ฌ๋ณผ์„ ํ‚ค๋กœ ๊ฐ–๋Š” object๋‹ค. ๋ฌธ์ž์—ด์ด๋‚˜ ์ˆซ์ž๊ฐ€ ์•„๋‹Œ ์‹ฌ๋ณผ์„ key๋กœ ๊ฐ–๋Š” ์†์„ฑ์ด๋‹ค. ์ด๋Š” ์œ ์ผ์„ฑ์„ ๋ณด์žฅํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค๋ฅธ ํ‚ค๋“ค๊ณผ์˜ ์ถฉ๋Œ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋‹ค๋งŒ obj.name๊ณผ ๊ฐ™์ด dot์„ ์ด์šฉํ•ด์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋‹ค. ๋ฐ˜๋“œ์‹œ []๋ฅผ ํ™œ์šฉํ•ด์„œ ์ ‘๊ทผํ•ด์•ผ ํ•œ๋‹ค.

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

๊ทธ๋ฆฌ๊ณ  ์‹ฌ๋ณผ ํ‚ค๋Š” ์ด๋Ÿฌํ•œ ์ถฉ๋Œ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด์„œ ๋งŒ๋“ค์–ด ์ง„ ๊ฒƒ์ด๋ฏ€๋กœ, ์ผ๋ฐ˜์ ์ธ javascript ๊ฐ์ฒด ์กฐ์‚ฌ๋Š” Symbol์„ ๋ฌด์‹œํ•œ๋‹ค. ๋ฌด์Šจ ์†Œ๋ฆฌ๋ƒ๋ฉด...

let ๋ฉ”์‹œ = {}
๋ฉ”์‹œ['์˜๋ฌธ๋ช…'] = 'Lionel Messi'
๋ฉ”์‹œ['๋ณ„๋ช…'] = '๋ผ์ด์˜ค๋„ฌ ๋ฉง์‹œ'
const Nationality = Symbol('์„ ์ˆ˜์˜ ๊ตญ์ ')
๋ฉ”์‹œ[Nationality] = '์น ๋ ˆ'

for (let i in ๋ฉ”์‹œ) {
  console.log(i)
}

for (let i of Object.keys(๋ฉ”์‹œ)) {
  console.log(i)
}

for (let i of Object.getOwnPropertyNames(๋ฉ”์‹œ)) {
  console.log(i)
}
"์˜๋ฌธ๋ช…"
"๋ณ„๋ช…"
"์˜๋ฌธ๋ช…"
"๋ณ„๋ช…"
"์˜๋ฌธ๋ช…"
"๋ณ„๋ช…"

์ด์ฒ˜๋Ÿผ ์‹ฌ๋ณผ Nationality ํ‚ค๋Š” ์ผ๋ฐ˜์ ์ธ ์ƒํ™ฉ์—์„œ ๋ชจ๋‘ ๋ฌด์‹œ ๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ๋ฌผ๋ก  ์ด๋ฅผ ์กฐํšŒํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ๋‹ค.

Object.getOwnPropertySymbols(๋ฉ”์‹œ)
[Symbol(์„ ์ˆ˜์˜ ๊ตญ์ )]

ํ˜น์€ ์‹ฌ๋ณผ์„ ํฌํ•จํ•ด์„œ ๋ชจ๋“  ํ‚ค๋ฅผ ์กฐํšŒํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด

Reflect.ownKeys(๋ฉ”์‹œ)
["์˜๋ฌธ๋ช…", "๋ณ„๋ช…", Symbol(์„ ์ˆ˜์˜ ๊ตญ์ )]

Reflect.ownKeys๋ฅผ ํ™œ์šฉํ•˜๋ฉด ๋œ๋‹ค.

์‹ฌ๋ณผ์˜ ํŠน์ง•

  • ์ผ๋‹จ ์ƒ์„ฑ๋˜๋ฉด ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š”๋‹ค
  • ์†์„ฑ์„ ๋ถ€์—ฌํ•  ์ˆ˜ ์—†๋‹ค
  • object์˜ key ๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋ชจ๋“  ์‹ฌ๋ณผ์€ ๊ณ ์œ ํ•˜๋‹ค. ์ฃผ์„์ด ๋™์ผํ•˜๋‹ค ํ•˜๋”๋ผ๋„ ์ผ๋‹จ ์ƒ์„ฑ๋˜๋ฉด ๋‹ค๋ฅด๊ฒŒ ๊ตฌ๋ณ„๋œ๋‹ค.
  • ๋ฌธ์ž์—ด๋กœ ์ž๋™์œผ๋กœ ๋ณ€ํ™˜๋˜์ง€ ์•Š๋Š”๋‹ค.
const newSymbol = Symbol(
  'this symbol',
)`symbol is ${newSymbol}` //Uncaught TypeError: Cannot convert a Symbol value to a string
`symbol is ${String(newSymbol)} ${newSymbol.toString()}`
// symbol is Symbol(this symbol) Symbol(this symbol)

์‹ฌ๋ณผ์„ ๊ฐ–๋Š” ๋ฐฉ๋ฒ•

  • Symbol()์„ ํ˜ธ์ถœํ•œ๋‹ค. ์ด๋Š” ํ˜ธ์ถœํ•  ๋•Œ ๋งˆ๋‹ค ์ƒˆ๋กญ๊ณ  ๊ณ ์œ ํ•œ ์‹ฌ๋ณผ์„ ๋งŒ๋“ค์–ด ์ค€๋‹ค.
  • Symbol.for(string)์„ ํ˜ธ์ถœํ•œ๋‹ค. ์ด ๋ฉ”์†Œ๋“œ๋Š” Symbol Registry๋ผ๋Š” ์‹ฌ๋ณผ๋ชฉ๋ก์„ ์ฐธ์กฐํ•˜์—ฌ ๋ฆฌํ„ดํ•˜๋Š”๋ฐ, ์•ž์„œ์™€๋Š” ๋‹ค๋ฅด๊ฒŒ ์‹ฌ๋ณผ ๋ชฉ๋ก์„ ๊ณต์œ ํ•œ๋‹ค. Symbol.for('ํ˜ธ๋‚ ๋„')๋ฅผ ๊ณ„์†ํ•ด์„œ ํ˜ธ์ถœํ•œ๋‹ค๋ฉด, ๋งค๋ฒˆ ๊ฐ™์€ ์‹ฌ๋ณผ์„ ๋ฆฌํ„ดํ•œ๋‹ค. ์ด๋Š” ์‹ฌ๋ณผ์ด ๊ณต์œ  ๋˜์–ด์•ผ ํ•˜๋Š” ์ƒํ™ฉ์—์„œ ์œ ์šฉํ•˜๋‹ค.
  • Symbol.length ์ฒ˜๋Ÿผ ํ‘œ์ค€์— ์ •์˜๋œ ์‹ฌ๋ณผ์„ ๊ฐ€์ ธ์˜ค๋Š” ๋ฒ•