Destructuing Assignment

About

JavaScript์—๋Š” ๊ตฌ์กฐ ๋ถ„ํ•ด ํ• ๋‹น(Destructuing Assignment)์ด๋ผ๋Š” ํŽธ๋ฆฌํ•œ ๋ฌธ๋ฒ•์ด ์žˆ๋‹ค. ๊ต‰์žฅํžˆ ๋งŽ์ด ์“ฐ์ด๋Š” ๋ฌธ๋ฒ•์ธ๋ฐ ํ•œ ๋ฒˆ ์•Œ์•„๋ณด์ž.

๋‚ด์šฉ์€ ์ „๋ถ€ MDN ๋ฌธ์„œ์—์„œ ๊ฐ€์ ธ์˜จ ๊ฒƒ์ด์ง€๋งŒ ์‹ค์ œ ๊ฐœ๋ฐœํ•˜๋ฉด์„œ ๊ฒช์€ ์˜ˆ์‹œ๋„ ์ค‘๊ฐ„ ์ค‘๊ฐ„ ๋„ฃ์–ด๋ณด์•˜๋‹ค.

๋ฌธ๋ฒ• (Syntax)

๊ฐœ์š”

=๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์™ผ์ชฝ์— ํ• ๋‹น๋ฐ›์„ ๋ณ€์ˆ˜๋ฅผ, ์˜ค๋ฅธ์ชฝ์— ๋ถ„ํ•ดํ•  ๋Œ€์ƒ์„ ์ ์–ด์„œ ์ˆœ์„œ๋Œ€๋กœ ๋Œ€์ž…ํ•  ์ˆ˜ ์žˆ๋‹ค.

const [a, b] = [10, 20]

console.log(a) // 10
console.log(b) // 20

a์—๋Š” 10, b์—๋Š” 20์ด ๋‹ด๊ธฐ๊ฒŒ ๋œ๋‹ค.

const x = [1, 2, 3, 4, 5]
const [y, z] = x
console.log(y) // 1
console.log(z) // 2

๋ฐฐ์—ด ๋ฐ ๊ฐ์ฒด

const obj = { a: 1, b: { c: 2 } }
const { a, b: { c: d} } = obj
// Two variables are bound: `a`, `d`
const obj = { a: 1, b: { c: 2 } }
const { a } = obj // `a`๋Š” ์ƒ์ˆ˜(constant)
let { b: { c: d } } = obj // `d`๋Š” ์žฌํ• ๋‹น์ด ๊ฐ€๋Šฅํ•˜๋‹ค
  • const๋กœ ํ•  ๊ฒฝ์šฐ ๋‚ด๋ถ€ ๋ณ€์ˆ˜๋Š” read-only์ด์ง€๋งŒ,

  • let์œผ๋กœ ํ•  ๊ฒฝ์šฐ ๋‚ด๋ถ€ ๋ณ€์ˆ˜๋Š” ์žฌํ• ๋‹น์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

const numbers = []
const obj = { a: 1, b: 2 }

({ a: numbers[0], b: numbers[1] } = obj)
// `a`, `b`๋Š” `numbers`์˜ ํ”„๋กœํผํ‹ฐ๋กœ ๋“ค์–ด๊ฐ„๋‹ค

์•ˆ๋˜๋Š” ๊ฒฝ์šฐ๋„ ์žˆ๋‹ค.

const numbers = []
const obj = { a: 1, b: 2 }
const { a: numbers[0], b: numbers[1] } = obj

// ์œ„ ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค:
//     const numbers[0] = obj.a
//     const numbers[1] = obj.b
// ๋”ฐ๋ผ์„œ ํ‹€๋ฆฌ๋‹ค.

๋””ํดํŠธ ๊ฐ’

๊ฐ ๊ตฌ์กฐ ๋ถ„ํ•ด๋œ ํ”„๋กœํผํ‹ฐ๋Š” ๋””ํดํŠธ ๊ฐ’์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค.

  • ํ”„๋กœํผํ‹ฐ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ undefined์ด๋ฉด ๋””ํดํŠธ ๊ฐ’์ด ์‚ฌ์šฉ๋œ๋‹ค.

  • ํ”„๋กœํผํ‹ฐ๊ฐ€ null ๊ฐ’์„ ๊ฐ€์ง€๋ฉด ๋””ํดํŠธ ๊ฐ’์ด ์ ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค.

const [a = 1] = [] // a is 1
const { b = 2 } = { b: undefined } // b is 2
const { c = 2 } = { c: null } // c is null

๋””ํดํŠธ ๊ฐ’์€ ํ‘œํ˜„์‹(expression)์ด ๋  ์ˆ˜๋„ ์žˆ๋‹ค. ํ•„์š”ํ•  ๋•Œ๋งŒ evaluated ๋œ๋‹ค.

const { b = console.log('hey') } = { b: 2 }
// `b`๊ฐ€ ์šฐ์ธก์— ์กด์žฌํ•˜๋ฏ€๋กœ ๋””ํดํŠธ ๊ฐ’์„ evaluate ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— console.log() ๋˜์ง€ ์•Š๋Š”๋‹ค.

Rest Property

๊ตฌ์กฐ ๋ถ„ํ•ด ํŒจํ„ด์„ ...rest์™€ ๊ฐ™์ด rest property๋กœ ๋๋‚ผ ์ˆ˜๋„ ์žˆ๋‹ค. ์ด ํŒจํ„ด์œผ๋กœ ๊ฐ์ฒด๋‚˜ ๋ฐฐ์—ด์˜ ๋‚จ์€ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋‚˜ ๋ฐฐ์—ด์— ํ• ๋‹นํ•  ์ˆ˜ ์žˆ๋‹ค.

const { a, ...others } = { a: 1, b: 2, c: 3 }
console.log(others) // { b: 2, c: 3 }

const [first, ...others2] = [1, 2, 3]
console.log(others2) // [2, 3]
  • Rest property๋Š” ๋งˆ์ง€๋ง‰์— ์žˆ์–ด์•ผ ํ•˜๋ฉฐ, trailing comma (,)๋ฅผ ๊ฐ€์ง€๋ฉด ์•ˆ๋œ๋‹ค.

๋‹ค๋ฅธ ๋ฌธ๋ฒ•์—์„œ์˜ ๊ตฌ์กฐ ๋ถ„ํ•ด ํŒจํ„ด

๋ณ€์ˆ˜๋ฅผ ๋ฐ”์ธ๋”ฉํ•˜๋Š” ๋‹ค๋ฅธ ๋งŽ์€ ๋ฌธ๋ฒ•์—์„œ ๊ตฌ์กฐ ๋ถ„ํ•ด ํŒจํ„ด์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์ž๋ฉด:

  • for...in, for...of ๋ฃจํ”„์˜ ๋ฃจํ”„ ๋ณ€์ˆ˜

  • ํ•จ์ˆ˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜

  • catch ๋ฐ”์ธ๋”ฉ ๋ณ€์ˆ˜

์˜ˆ์‹œ (Examples)

๋ฐฐ์—ด ๊ตฌ์กฐ ๋ถ„ํ•ด

๊ธฐ๋ณธ์ ์ธ ๋ฐฐ์—ด ํ• ๋‹น

const foo = ['one', 'two', 'three']

const [red, yellow, green] = foo
console.log(red) // "one"
console.log(yellow) // "two"
console.log(green) // "three"

์†Œ์Šค๋ณด๋‹ค ๋งŽ์€ ์›์†Œ ๊ตฌ์กฐ ๋ถ„ํ•ด

const foo = ['one', 'two']

const [red, yellow, green, blue] = foo
console.log(red) // "one"
console.log(yellow) // "two"
console.log(green) // undefined
console.log(blue) // undefined 

๋ณ€์ˆ˜ ์Šค์™‘ํ•˜๊ธฐ (Swapping variables)

let a = 1
let b = 3

[a, b] = [b, a]
console.log(a) // 3
console.log(b) // 1

const arr = [1, 2, 3]
[arr[2], arr[1]] = [arr[1], arr[2]]
console.log(arr) // [1, 3, 2]

ํ•จ์ˆ˜๋กœ๋ถ€ํ„ฐ ๋ฐ˜ํ™˜๋œ ๋ฐฐ์—ด ํŒŒ์‹ฑํ•˜๊ธฐ

ํ•จ์ˆ˜๋กœ๋ถ€ํ„ฐ ๋ฐ˜ํ™˜๋œ ๋ฐฐ์—ด ๊ฐ’์„ ์ข€๋” ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.

function f() {
  return [1, 2]
}

const [a, b] = f()
console.log(a) // 1
console.log(b) // 2

๋ฐ˜ํ™˜ ๊ฐ’ ์ผ๋ถ€ ๋ฌด์‹œํ•˜๊ธฐ

function f() {
  return [1, 2, 3]
}

const [a, , b] = f()
console.log(a) // 1
console.log(b) // 3

const [c] = f()
console.log(c) // 1

๋ฐ”์ธ๋”ฉ ํŒจํ„ด์„ Rest Property๋กœ ์‚ฌ์šฉํ•˜๊ธฐ

๋ฐฐ์—ด์˜ ๊ตฌ์กฐ ๋ถ„ํ•ด ํ• ๋‹น์—์„œ์˜ rest property๋Š” ๋˜ ๋‹ค๋ฅธ ๋ฐฐ์—ด์ด๋‚˜ ๊ฐ์ฒด์˜ ๋ฐ”์ธ๋”ฉ ํŒจํ„ด์ด ๋  ์ˆ˜ ์žˆ๋‹ค. ์ด ๋ฐฉ๋ฒ•์œผ๋กœ ๋™์‹œ์— ํ”„๋กœํผํ‹ฐ๋‚˜ ๋ฐฐ์—ด์˜ ์ธ๋ฑ์Šค๋ฅผ ๋ถ„๋ฆฌ(unpack)ํ•  ์ˆ˜ ์žˆ๋‹ค.

const [a, b, ...{ pop, push }] = [1, 2]
console.log(a, b) // 1 2
console.log(pop, push) // [Function pop] [Function push]
const [a, b, ...[c, d]] = [1, 2, 3, 4]
console.log(a, b, c, d) // 1, 2, 3, 4

์ด๋Ÿฐ ๋ฐ”์ธ๋”ฉ ํŒจํ„ด์€ ๊ฐ rest property๊ฐ€ ๋งˆ์ง€๋ง‰์— ์œ„์น˜ํ•œ ํ•œ ์ค‘์ฒฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

const [a, b, ...[c, d, ...[e, f]]] = [1, 2, 3, 4, 5, 6]
console.log(a, b, c, d, e, f) // 1 2 3 4 5 6

Warning: ํ•˜์ง€๋งŒ ๊ฐ์ฒด์˜ ๊ตฌ์กฐ ๋ถ„ํ•ด๋Š” identifier๋งŒ์ด rest property๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค.

const { a, ...{ b } } = { a: 1, b: 2 }
// SyntaxError: `...` must be followed by an identifier in declaration contexts

let a, b;
({ a, ...{ b } } = { a: 1, b: 2 })
// SyntaxError: `...` must be followed by an assignable reference in assignment contexts

์ •๊ทœ ํ‘œํ˜„์‹์œผ๋กœ ๋ถ„๋ฆฌ(unpacking)ํ•˜๊ธฐ

์ •๊ทœํ‘œํ˜„์‹์˜ exec() ๋ฉ”์†Œ๋“œ๊ฐ€ ๋งค์น˜๋ฅผ ์ฐพ์œผ๋ฉด ์ฒซ ๋ฒˆ์งธ ์š”์†Œ๋กœ ๋ฌธ์ž์—ด์—์„œ ๋งค์น˜๋œ ๋ถ€๋ถ„ ์ „์ฒด (full match)๋ฅผ, ๊ทธ๋ฆฌ๊ณ  ๋‚˜๋จธ์ง€ ์š”์†Œ๋กœ ()๋กœ ๊ทธ๋ฃนํ™”๋œ ๊ฒƒ์— ๋งค์น˜๋˜๋Š” ๋ฌธ์ž์—ด์˜ ๋ถ€๋ถ„๋“ค์„ ๊ฐ–๋Š” ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

๊ตฌ์กฐ ๋ถ„ํ•ด ํ• ๋‹น์œผ๋กœ full match๋ฅผ ๋ฌด์‹œํ•˜๊ณ  ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„์„ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

function parseProtocol(url) {
  const parsedURL = /^(\w+):\/\/([^/]+)\/(.*)$/.exec(url)
  if (!parsedURL) {
    return false
  }
  console.log(parsedURL)
  // ["https://developer.mozilla.org/en-US/docs/Web/JavaScript",
  // "https", "developer.mozilla.org", "en-US/docs/Web/JavaScript"]

  const [, protocol, fullhost, fullpath] = parsedURL
  return protocol
}

console.log(parseProtocol('https://developer.mozilla.org/en-US/docs/Web/JavaScript'))
// "https"

์–ด๋–ค iterable์ด๋“  ๋ฐฐ์—ด ๊ตฌ์กฐ ๋ถ„ํ•ด ์‚ฌ์šฉํ•˜๊ธฐ

const [a, b] = new Map([[1, 2], [3, 4]])
console.log(a, b) // [1, 2] [3, 4]

๋ฐฐ์—ด ๊ตฌ์กฐ ๋ถ„ํ•ด๋Š” right-hand side์—์„œ iterable ํ”„๋กœํ† ์ฝœ์„ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์–ด๋–ค iterable์ด๋“  ๊ตฌ์กฐ ๋ถ„ํ•ด๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

๊ฐ์ฒด ๊ตฌ์กฐ ๋ถ„ํ•ด

๊ธฐ๋ณธ ํ• ๋‹น

const user = {
  id: 42,
  isVerified: true,
}

const { id, isVerified } = user

console.log(id) // 42
console.log(isVerified) // true

์ƒˆ๋กœ์šด ๋ณ€์ˆ˜ ์ด๋ฆ„์„ ํ• ๋‹นํ•˜๊ธฐ

const o = { p: 42, q: true }
const { p: foo, q: bar } = o

console.log(foo) // 42
console.log(bar) // true
  • p๋ฅผ foo๋กœ, q๋ฅผ bar๋กœ ๋ฐ›๋Š”๋‹ค.

์ƒˆ๋กœ์šด ๋ณ€์ˆ˜ ์ด๋ฆ„์„ ํ• ๋‹นํ•˜๊ณ  ๋””ํดํŠธ ๊ฐ’ ์„ค์ •ํ•˜๊ธฐ

ํ”„๋กœํผํ‹ฐ์— ๋Œ€ํ•ด์„œ ๋‹ค์Œ ๋‘ ๊ฐ€์ง€ ์ž‘์—…์„ (๋™์‹œ์—) ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ๊ฐ์ฒด๋กœ๋ถ€ํ„ฐ ๋ถ„๋ฆฌ(unpack)ํ•ด ์ƒˆ๋กœ์šด ์ด๋ฆ„์˜ ๋ณ€์ˆ˜๋กœ ํ• ๋‹นํ•˜๊ธฐ

  • ๋ถ„๋ฆฌ๋œ(unpacked) ๊ฐ’์ด undefined์ผ ๊ฒฝ์šฐ์— ๋Œ€๋น„ํ•ด ๋””ํดํŠธ ๊ฐ’ ์„ค์ •ํ•˜๊ธฐ

const { a: aa = 10, b: bb = 5 } = { a: 3 }

console.log(aa) // 3
console.log(bb) // 5

ํ•จ์ˆ˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌ๋œ ๊ฐ์ฒด๋กœ๋ถ€ํ„ฐ ํ”„๋กœํผํ‹ฐ ๋ถ„๋ฆฌํ•˜๊ธฐ(Unpacking)

const user = {
  id: 42,
  displayName: 'jdoe',
  fullName: {
    firstName: 'John',
    lastName: 'Doe',
  },
};

// `user`์—์„œ `id`๋งŒ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.
function userId({ id }) {
  return id
}

console.log(userId(user)) // 42

// ์ค‘์ฒฉ๋œ ํ”„๋กœํผํ‹ฐ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.
function whois({ displayName, fullName: { firstName: name } }) {
  return `${displayName} is ${name}`
}

console.log(whois(user))  // "jdoe is John"

ํ•จ์ˆ˜ ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ๋””ํดํŠธ ๊ฐ’ ์„ค์ •ํ•˜๊ธฐ

function drawChart({ size = 'big', coords = { x: 0, y: 0 }, radius = 25 } = {}) {
  console.log(size, coords, radius)
  // do some chart drawing
}

drawChart({
  coords: { x: 18, y: 30 },
  radius: 30,
})

์ค‘์ฒฉ๋œ ๊ฐ์ฒด์™€ ๋ฐฐ์—ด ๊ตฌ์กฐ ๋ถ„ํ•ด

const metadata = {
  title: 'Scratchpad',
  translations: [
    {
      locale: 'de',
      localizationTags: [],
      lastEdit: '2014-04-14T08:43:37',
      url: '/de/docs/Tools/Scratchpad',
      title: 'JavaScript-Umgebung',
    },
  ],
  url: '/en-US/docs/Tools/Scratchpad',
}

const {
  title: englishTitle, // rename
  translations: [
    {
      title: localeTitle, // rename
    },
  ],
} = metadata

console.log(englishTitle) // "Scratchpad"
console.log(localeTitle)  // "JavaScript-Umgebung"

for...of ๋ฐ˜๋ณต๊ณผ ๊ตฌ์กฐ ๋ถ„ํ•ด

const people = [
  {
    name: 'Mike Smith',
    family: {
      mother: 'Jane Smith',
      father: 'Harry Smith',
      sister: 'Samantha Smith',
    },
    age: 35,
  },
  {
    name: 'Tom Jones',
    family: {
      mother: 'Norah Jones',
      father: 'Richard Jones',
      brother: 'Howard Jones',
    },
    age: 25,
  }
]

for (const { name: n, family: { father: f } } of people) {
  console.log(`Name: ${n}, Father: ${f}`)
}

// "Name: Mike Smith, Father: Harry Smith"
// "Name: Tom Jones, Father: Richard Jones"

๊ณ„์‚ฐ๋œ(Computed) ๊ฐ์ฒด ํ”„๋กœํผํ‹ฐ ์ด๋ฆ„๊ณผ ๊ตฌ์กฐ ๋ถ„ํ•ด

const key = 'z'
const { [key]: foo } = { z: 'bar' }

console.log(foo) // "bar"

์˜ฌ๋ฐ”๋ฅด์ง€ ์•Š์€ JavaScript ์‹๋ณ„์ž๋ช…์„ ํ”„๋กœํผํ‹ฐ ์ด๋ฆ„์œผ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ

const foo = { 'fizz-buzz': true }
const { 'fizz-buzz': fizzBuzz } = foo

console.log(fizzBuzz) // true

๋ฐฐ์—ด๊ณผ ๊ฐ์ฒด๊ฐ€ ํ•ฉ์ณ์ง„ ํ˜•ํƒœ์˜ ๊ตฌ์กฐ ๋ถ„ํ•ด

๋ฐฐ์—ด๊ณผ ๊ฐ์ฒด ๊ตฌ์กฐ ๋ถ„ํ•ด๋ฅผ ๋™์‹œ์— ํ•  ์ˆ˜ ์žˆ๋‹ค.

const props = [
  { id: 1, name: 'Fizz'},
  { id: 2, name: 'Buzz'},
  { id: 3, name: 'FizzBuzz'}
]

const [,, { name }] = props

console.log(name) // "FizzBuzz"

๊ฐ์ฒด๊ฐ€ ๊ตฌ์กฐ ๋ถ„ํ•ด๋  ๋•Œ ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ(Prototype chain)๋ฅผ ๋”ฐ๋ผ๊ฐ€ ์ฐพ์•„๊ฐ„๋‹ค

๊ฐ์ฒด๋ฅผ ๊ตฌ์กฐ ๋ถ„ํ•ดํ•  ๋•Œ, ํ”„๋กœํผํ‹ฐ๊ฐ€ ํ•ด๋‹น ํ”„๋กœํผํ‹ฐ ์•ˆ์— ์—†๋‹ค๋ฉด(not accessed in itself) ํ”„๋กœํ† ํƒ€์ž… ์ฒด์ธ์„ ๋”ฐ๋ผ์„œ ๊ณ„์†ํ•ด์„œ ์ฐพ์•„๊ฐˆ ๊ฒƒ(look up)์ด๋‹ค.

const obj = {
  self: '123',
  __proto__: {
    prot: '456',
  },
}
const { self, prot } = obj
// self "123"
// prot "456" (Access to the prototype chain) 

๊ฒฐ๋ก  (Conclusion)

์ •๋ฆฌํ•˜๊ณ  ๋ณด๋‹ˆ ์“ฐ์ž„์ƒˆ๊ฐ€ ์ƒˆ์‚ผ ์ฐธ ๋งŽ๋‹ค. (์ •๋ฆฌํ•˜๋‹ค๊ฐ€ ๋ช‡ ๋ฒˆ ์กธ์•˜๋‹ค. ๐Ÿฅฑ)

๊ทผ๋ฐ ๋ณด๋ฉด ์•Œ๊ฒ ์ง€๋งŒ Examples ์„น์…˜์— ์žˆ๋Š” ๋‚ด์šฉ์ด ๋ฐ˜ ์ด์ƒ์ด๋‹ค. ์˜ˆ์‹œ๊ฐ€ ๋‹ค์–‘ํ•ด์„œ ๋งŽ์•„ ๋ณด์ด๋Š” ๊ฒƒ์ด์ง€, ์‚ฌ์šฉ๋ฒ•๊ณผ ์›๋ฆฌ๋งŒ ์•Œ๋ฉด ์ž์œ ๋กญ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์ œ์ผ ์ค‘์š”ํ•œ ๊ฑด ๊ฒฝํ—˜์„ ํ†ตํ•ด ๊ตฌ์กฐ ๋ถ„ํ•ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ ํ•ฉํ•œ์ง€๋ฅผ ์ฒด๋“ํ•˜๊ณ  ์ ์žฌ์ ์†Œ์— ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

REF

Last updated

Was this helpful?