Shallow Copying Objects

1. Koans ๊ณผ์ œ 07_Object ๋งจ ๋งˆ์ง€๋ง‰ ๋ฌธ์ œ (true? false?)

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ Koans ๊ณผ์ œ๋ฅผ ๋‹ค์‹œ ์ฒœ์ฒœํžˆ ํ’€๋ฉฐ ์ฝ์–ด๋ณด๋‹ค๊ฐ€ 07๋ฒˆ ์ฃผ์ œ object ๋งจ ์•„๋ž˜์— ์žˆ๋Š” ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋ฅผ ์ž‘์„ฑํ•˜๋Š” ์™€์ค‘์— ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒผ๋‹ค.

it('Object๋ฅผ ํ•จ์ˆ˜์˜ ์ธ์ž๋กœ ์ „๋‹ฌํ•  ๊ฒฝ์šฐ, reference๊ฐ€ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค.', function() {
  const obj = {
    mastermind: 'Joker',
    henchwoman: 'Harley',
    relations: ['Anarky', 'Duela Dent', 'Lucy'],
    twins: {
      'Jared Leto': 'Suicide Squad',
      'Joaquin Phoenix': 'Joker',
      'Heath Ledger': 'The Dark Knight',
      'Jack Nicholson': 'Tim Burton Batman',
    },
  }

  function passedByReference(refObj) {
    refObj.henchwoman = 'Adam West'
  }
  passedByReference(obj)
  expect(obj.henchwoman).toBe('Adam West')

  const assignedObj = obj
  assignedObj['relations'] = [1, 2, 3]
  expect(obj['relations']).toEqual([1, 2, 3])

  const copiedObj = Object.assign({}, obj) // Object.assign(target, source);
  copiedObj.mastermind = 'James Wood'
  expect(obj.mastermind).toBe('Joker')

  obj.henchwoman = 'Harley'
  expect(copiedObj.henchwoman).toBe('Adam West')

  delete obj.twins['Jared Leto']
  expect('Jared Leto' in copiedObj.twins).toBe(false)
})

์ฝ”๋“œ ๋งจ ์•„๋ž˜์˜ toBe ๋ž€์— true ๋กœ ์ ์—ˆ๋Š”๋ฐ false ๊ฐ€ ๋งž๋‹ค๋Š” ๊ฒƒ์— ๋„์ €ํžˆ ๋‚ฉ๋“์ด ์•ˆ๋œ๋‹ค๋Š” ๊ฒƒ์ด ๋ฌธ์ œ์˜€๋‹ค.

delete obj.twins['Jared Leto']
expect('Jared Leto' in copiedObj.twins).toBe(false)

try1

์•„๋ฌด๋ฆฌ ์ƒ๊ฐํ•ด๋„ ๋ฏฟ๊ธฐ์ง€ ์•Š์•„์„œ ์ฝ˜์†”๋กœ๋„ ์ฐ์–ด์„œ ์‹คํ–‰ํ•ด ๋ดค๋Š”๋ฐ ๋งˆ์ฐฌ๊ฐ€์ง€๋‹ค. ์™œ์ผ๊นŒ?

์ด ๋ฌธ์ œ์—์„œ ๋‚ด๊ฐ€ ์ดํ•ดํ•˜๊ณ  ์žˆ๋Š” ๋ถ€๋ถ„์€ const copiedObj = Object.assign({}, obj) ์„ ํ†ตํ•ด ๋ณต์‚ฌ๋œ copiedObj ๋ณ€์ˆ˜๋Š”, obj ๋ณ€์ˆ˜์™€๋Š” ๋‹ค๋ฅธ ์ฃผ์†Œ์˜ ๊ฐ์ฒด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฐ์ฒด ๋ผ๊ณ  ์ดํ•ดํ–ˆ๋‹ค.

๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์—, copiedObj.mastermind = โ€˜James Woodโ€™; ๋ฅผ ํ†ตํ•ด copiedObj ์˜ ํ‚ค mastermind ์˜ ๊ฐ’์ด โ€˜James Woodโ€™ ๋กœ ๋ฐ”๋€Œ์–ด๋„, obj ๋ณ€์ˆ˜์˜ ํ‚ค mastermind ๋Š” ์—ฌ์ „ํžˆ โ€˜Jokerโ€™ ์ธ ๊ฒƒ์ด๋‹ค.

์ฆ‰ ๋‘ ๋ณ€์ˆ˜๋Š” ์„œ๋กœ ์ƒ๊ด€์ด ์—†๋Š” ๊ฒƒ์ธ๋ฐ,

ํ•˜์ง€๋งŒ, delete obj.twins[โ€˜Jared Letoโ€™]; ๋ฅผ ํ†ตํ•ด obj ๊ฐ์ฒด ๋‚ด ๋ญ”๊ฐ€ ์ง€์›Œ์กŒ๋‹ค ํ•˜๋”๋ผ๋„, copiedObj ๋ณ€์ˆ˜์—๋Š” ์ „ํ˜€ ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋Š” ๊ฑฐ ์ผํ…๋ฐ ์ฝ˜์†”์„ ์ง์ ‘ ์ฐ์–ด๋ณด๋‹ˆ copiedObj ์˜ ๊ฐ์ฒด์—์„œ๋„ copiedObj.twins[โ€˜Jared Letoโ€™] ๊ฐ€ ์ง€์›Œ์กŒ๋‹ค๋Š” ๊ฒƒ์ด ๋‚ฉ๋“์ด ์•ˆ๋˜๋Š” ๊ฒƒ์ด์˜€๋‹ค.

๊ทธ๋ž˜์„œ ํ—ฌํ”„ ๋ฐ์Šคํฌ์— ์งˆ๋ฌธ์„ ํ–ˆ๋‹ค.

์„ ์ƒ๋‹˜๊ป˜์„œ๋Š” ๊นŠ์€ ๋ณต์‚ฌ์™€ ์–•์€ ๋ณต์‚ฌ๋ฅผ ํ‚ค์›Œ๋“œ๋กœ ๊ฒ€์ƒ‰ํ•ด์„œ ๊ณต๋ถ€ํ•ด ๋ณด๋ผ ํ•˜์…จ๋‹ค.

2. ๊ฐ์ฒด์˜ ์–•์€ ๋ณต์‚ฌ, ๊นŠ์€ ๋ณต์‚ฌ.

๊ทธ๋ž˜์„œ ํ‚ค์›Œ๋“œ ๊ฒ€์ƒ‰์„ ํ•ด๋ณด๋‹ˆ, ์—ฌ๋Ÿฌ ํŽ˜์ด์ง€์—์„œ ํ™•์ธํ•ด ๋ณด์•˜๋Š”๋ฐ ์„ค๋ช…์ด ๋„ˆ๋ฌด ์–ด๋ ค์›Œ ์ฝ๋‹ค๊ฐ€ ๊ป๋‹ค.

https://ithub.tistory.com/301

์œ„ ์‚ฌ์ดํŠธ์—์„œ ์–•์€ ๋ณต์‚ฌ์™€ ๊นŠ์€ ๋ณต์‚ฌ์˜ ์˜๋ฏธ๋ฅผ ์งง๊ฒŒ ๋‹ค๋ฃจ๋Š” ๋ฌธ์žฅ์„ ๊ทธ๋Œ€๋กœ ์˜ฎ๊ฒจ ์™”๋‹ค.

์–•์€ ๋ณต์‚ฌ๋ž€, ๊ฐ์ฒด์˜ ์ฒซ ๋ฒˆ์งธ ๋ถ€๋ถ„๋งŒ ๋ณต์‚ฌํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
Object์˜ ๋‚ด์žฅ๊ฐ์ฒด์ธ assign() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.


๊นŠ์€ ๋ณต์‚ฌ๋ž€, nestedํ•œ ๊ฐ์ฒด์˜ ๋ชจ๋“  ํ•˜์œ„ ๊ฐ์ฒด๊นŒ์ง€ ๋ณต์‚ฌํ•˜๋Š” ๊ฒƒ์„ ๋งํ•ฉ๋‹ˆ๋‹ค.
JSON.parse()์™€ JSON.stringify() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.

์–•์€ ๋ณต์‚ฌ ์ชฝ ๋ฌธ์žฅ์„ ์ฝ๋‹ค๊ฐ€ assign() ํ•จ์ˆ˜๋ฅผ ๋ณด๊ณ  ์•„๊นŒ ๊ฐ’์„ ๋ณต์‚ฌํ•ด ์ฃผ๋Š” ๋ฐ ์ผ๋˜,

const copiedObj = Object.assign({}, obj);

๋ฅผ ๋– ์˜ฌ๋ฆฌ๊ณ  ์ดํ•ดํ•ด ๋ณด๊ธฐ ์œ„ํ•ด ์ฝ˜์†” ์ฐฝ์„ ์—ด์–ด ๋‹ค์‹œ ์ž…๋ ฅํ•ด๋ณด๊ธฐ ์‹œ์ž‘ํ–ˆ๋‹ค.

3. ์–•์€ (Shallow) ๋ณต์‚ฌ ์ดํ•ดํ•˜๊ธฐ

ํ—ฌํ”„ ๋ฐ์Šคํฌ์— ๊ณ ๋ฏผ์„ ํ•˜๋ฉด์„œ ๋‚จ๊ธด ๊ธ€์„ ๊ทธ๋Œ€๋กœ ์˜ฎ๊ฒจ์™€๋„ ์ข‹์„ ๊ฑฐ ๊ฐ™๋‹ค.

์ผ๋ฐ˜์ ์œผ๋กœ ์˜ค๋ธŒ์ ํŠธํ˜•(๋ฐฐ์—ด, ๊ฐ์ฒด, ํ•จ์ˆ˜) ์„ ์ž„์˜์˜ ๋ณ€์ˆ˜์— ํ• ๋‹นํ•˜๋ฉด, ๋ฉ”๋ชจ๋ฆฌ ์ƒ์— ์–ด๋–ค ๋ฐฐ์—ด์˜ ์ฃผ์†Œ๋ฅผ ๋ณ€์ˆ˜๊ฐ€ ๋ฐ”๋ผ๋ณด๊ณ  ์žˆ์œผ๋ฏ€๋กœ ๋ณ€์ˆ˜์— ์˜ค๋ธŒ์ ํŠธํ˜•์„ ํ• ๋‹นํ•œ ๋‹ค๋Š” ๊ฒƒ ์ž์ฒด๊ฐ€ ํ•ด๋‹น ์˜ค๋ธŒ์ ํŠธ์˜ ์ฃผ์†Œ๋ฅผ ํ• ๋‹น ํ•œ๋‹ค ๋ผ๊ณ  ์ดํ•ดํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ ๋งŒ์•ฝ,

const obj1 = {key:'value', key2:'value2};
const obj2 = obj;

๊ณผ ๊ฐ™์€ ํ˜•ํƒœ๋กœ ์„ ์–ธ์„ ํ•˜๋ฉด ๋ณ€์ˆ˜ obj1 ํ•˜๊ณ  obj2 ๊ฐ€ ๋™์ผํ•œ ๋ฉ”๋ชจ๋ฆฌ์ƒ์˜ ์ฃผ์†Œ๋ฅผ ์ฐธ์กฐ (ref) ํ•œ๋‹ค๊ณ  ๋ฐฐ์› ์Šต๋‹ˆ๋‹ค.

๋Œ€์‹  ์ด๋ ‡๊ฒŒ ๋˜๋ฉด obj2 ์˜ ํ‚ค๊ฐ’์„ ์ˆ˜์ •ํ•˜๋ฉด obj1 ๋„ ๋™์ผ ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ๋ฅผ ์ฐธ์กฐํ•˜๋ฏ€๋กœ obj1 ๋„ obj2 ์˜ ์ˆ˜์ •์‚ฌํ•ญ ๋Œ€๋กœ ๋ฐ”๋€Œ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์•„๋งˆ ๋‚˜์ค‘์— ๊ฐœ๋ฐœ์ž๊ฐ€ ๋˜์—ˆ์„ ๋•Œ, ์›๋ณธ ๊ฐ์ฒด๋ฅผ ์ €์žฅํ•œ ๋ณ€์ˆ˜์™€ ๊ทธ ๋ณ€์ˆ˜์™€ ๋˜‘๊ฐ™์€ ๊ฐ์ฒด๋ฅผ ๋ณ„๋„๋กœ ๋‘์–ด์„œ ๊ด€๋ฆฌํ•˜๊ณ  ์ˆ˜์ •์„ ํ•ด์•ผ ์›๋ณธ์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š์œผ๋ฏ€๋กœ, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ์˜ค๋ธŒ์ ํŠธ ์ž๋ฃŒํ˜•์„ ์œ„ํ•ด์„œ ๋ณต์‚ฌ ๋ผ๋Š” ๊ฐœ๋…์„ ๋„์ž…ํ•˜๊ฒŒ ๋˜์ง€ ์•Š์•˜๋‚˜ ํ•ฉ๋‹ˆ๋‹ค.

๊ฐ์ฒด ์ž๋ฃŒํ˜•์—์„œ์˜ ๋ณต์‚ฌ๋Š” Object.assign({}, obj); ์„ ์ด์šฉํ•˜๋Š”๋ฐ, ์ด๊ฒƒ์ด ์–•์€ ๋ณต์‚ฌ์ธ ์ด์œ ๋Š” ๊ทธ ๊ฐ์ฒด ๋‚ด ํ‚ค:๊ฐ’ ์˜ 1๋‹จ๊ณ„ ํ˜•ํƒœ๋งŒ์„ ๋ณต์‚ฌํ•ด ์˜ค๊ธฐ ๋•Œ๋ฌธ์ด๋ผ๋Š” ๊ฒƒ์„ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค.

์ฝ˜์†”๋กœ ์ง์ ‘ ์–ด๋–ป๊ฒŒ ๋‚˜์˜ค๋Š”์ง€ ํ™•์ธํ•ด ๋ณด์•˜์Šต๋‹ˆ๋‹ค.

const obj = {
      mastermind: 'Joker',
      henchwoman: 'Harley',
      relations: ['Anarky', 'Duela Dent', 'Lucy'],
      twins: {
        'Jared Leto': 'Suicide Squad',
        'Joaquin Phoenix': 'Joker',
        'Heath Ledger': 'The Dark Knight',
        'Jack Nicholson': 'Tim Burton Batman',
      },
    };

const copiedObj = Object.assign({}, obj);
copiedObj.mastermind = 'James Wood';
copiedObj
{mastermind: "James Wood", henchwoman: "Harley", relations: Array(3), twins: {โ€ฆ}}
obj
{mastermind: "Joker", henchwoman: "Harley", relations: Array(3), twins: {โ€ฆ}}

obj.henchwoman = 'codestates';
obj
{mastermind: "Joker", henchwoman: "codestates", relations: Array(3), twins: {โ€ฆ}}

copiedObj
{mastermind: "James Wood", henchwoman: "Harley", relations: Array(3), twins: {โ€ฆ}}

copiedObj.relations = ['tiger','lion','bear'];
copiedObj.relations
(3) ["tiger", "lion", "bear"]

obj.relations
(3) ["Anarky", "Duela Dent", "Lucy"]

์ด๋ ‡๋“ฏ ๋ณต์‚ฌ๊ฐ€ ์ž˜ ์ด๋ฃจ์–ด์ ธ์„œ ๋ณ€์ˆ˜ copiedObj ๊ฐ€ ๋ฌด์—‡์„ ์ˆ˜์ •ํ•ด๋„ ์›๋ณธ์ธ ๋ณ€์ˆ˜ obj ์— ์•„๋ฌด ์˜ํ–ฅ์„ ์•ˆ์ฃผ๊ณ  ๋ณ€์ˆ˜ ์ œ๊ฐ๊ฐ ๋…๋ฆฝ์ ์œผ๋กœ ์›€์ง์ด๋Š” ๊ฑฐ ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ ๋ฐ”๋กœ ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด,

obj.twins["Heath Ledger"] = "Code Knight";
"Code Knight"

obj.twins
{Jared Leto: "Suicide Squad", Joaquin Phoenix: "Joker", Heath Ledger: "Code Knight", Jack Nicholson: "Tim Burton Batman"}

copiedObj.twins
{Jared Leto: "Suicide Squad", Joaquin Phoenix: "Joker", Heath Ledger: "Code Knight", Jack Nicholson: "Tim Burton Batman"}

์–•์€ ๋ณต์‚ฌ์˜ ์˜๋ฏธ๋ฅผ ์–ด๋ ดํ’‹์ด ์ดํ•ดํ•œ ๋ฐ”๋กœ๋Š” ์–ด๋–ค ๊ฐ์ฒด๋ฅผ Object.assign({}, obj); ๋กœ ๋ณต์‚ฌํ•˜๋ฉด ๊ฐ์ฒด์˜ 1๋‹จ๊ณ„ ํ˜•ํƒœ์—์„œ๋Š” ๋ณต์‚ฌ๊ฐ€ ์ผ์–ด๋‚˜์ง€๋งŒ,

๊ฐ์ฒด์˜ 2๋‹จ๊ณ„ ๊ทธ๋Ÿฌ๋‹ˆ๊นŒ ๊ฐ์ฒด์˜ ํ‚ค ๋ฐธ๋ฅ˜๊ฐ€ ๋˜ ๊ฐ์ฒด์ผ๋•Œ,

2๋‹จ๊ณ„ ๊ฐ์ฒด์˜ ๊ฐ’์€ ๋ณต์‚ฌ๊ฐ€ ์ผ์–ด๋‚˜์ง€ ์•Š๊ณ  2๋‹จ๊ณ„ ๋‚ด์—์„œ๋Š” obj, copiedObj ๋ณ€์ˆ˜๊ฐ€ ๋™์ผํ•œ ์ฃผ์†Œ๋ฅผ ๋ฐ”๋ผ๋ณด๊ฒŒ ๋œ๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

์‰ฝ๊ฒŒ ๋งํ•˜๋ฉด ๊ฐ์ฒด ๋‚ด ํ‚ค ๋ฐธ๋ฅ˜์— ๊ฐ์ฒด๊ฐ€ ์žˆ๋‹ค๋ฉด ๊ทธ 2๋‹จ๊ณ„ ๊ฐ์ฒด ๋ฐ”๊นฅ ๊ป๋ฐ๊ธฐ๋งŒ ๋ณต์‚ฌ๊ฐ€ ๋œ๋‹ค ์ด๋ ‡๊ฒŒ ์ƒ๊ฐํ•˜๋ฉด ๋  ๊ฑฐ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์—ฌํŠผ ๊ทธ๋ž˜์„œ obj ์˜ 2๋‹จ๊ณ„์˜ (2๋‹จ๊ฐ์ฒด?!) ํ‚ค๋ฐธ๋ฅ˜์— ์ ‘๊ทผํ•ด ์ˆ˜์ •์„ ํ•˜๋ฉด ๊ทธ 2๋‹จ๊ณ„ ์•ˆ์—์„œ ๋งŒํผ์€ ๋™์ผํ•œ ์ฃผ์†Œ๋ฅผ ๋ฐ”๋ผ๋ณด๋ฏ€๋กœ copiedObj ๋„ ๋˜‘๊ฐ™์ด ๋ฐ”๋€Œ์–ด ๋ฒ„๋ฆฐ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์™„์ „ํ•œ ๋ณต์‚ฌ๊ฐ€ ์ผ์–ด๋‚˜์ง€ ์•Š์€ ๋ง๊ทธ๋Œ€๋กœ โ€œ์–•์€ ๋ณต์‚ฌโ€ ์ธ ์šฉ์–ด๊ฐ€ ์ดํ•ด๊ฐ€ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

try2

๊นŠ์€ ๋ณต์‚ฌ๋ฅผ ํ•˜๋ ค๋ฉด.

๊นŠ์€ ๋ณต์‚ฌ๋ž€, nestedํ•œ ๊ฐ์ฒด์˜ ๋ชจ๋“  ํ•˜์œ„ ๊ฐ์ฒด๊นŒ์ง€ ๋ณต์‚ฌํ•˜๋Š” ๊ฒƒ์„ ๋งํ•ฉ๋‹ˆ๋‹ค.
JSON.parse()์™€ JSON.stringify() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค

๊นŠ์€ ๋ณต์‚ฌ๋Š” ์‹œ๋„ํ•ด ๋ณด์ง€ ์•Š์•˜์ง€๋งŒ ์–•์€ ๋ณต์‚ฌ์— ๋Œ€ํ•ด ์–ผ๋งˆ ์ •๋„ ์ดํ•ด๊ฐ€ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋Š” ๊ฒƒ์€ ํ˜„์—…์— ๊ฐ€๋ฉด์€ ์–•์€ ๋ณต์‚ฌ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃฐ ๋•Œ ๊ฐ€๊ธ‰์  ํ”ผํ•ด์•ผ ๊ฒ ๋‹ค๋Š” ๋ง๋„ ๋˜๊ฒ ๋„ค์š”.

๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

4. conclusion

์–•์€ ๋ณต์‚ฌ์— ๋Œ€ํ•ด ์–ด๋Š ์ •๋„ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์–ด ์ข‹์•˜๋‹ค.


Written by@[DotoriMook]
ํ”„๋ก ํŠธ์—”๋“œ ์ฃผ๋‹ˆ์–ด ๊ฐœ๋ฐœ์ž ๋„ํ† ๋ฆฌ๋ฌต์˜ ๊ธฐ์ˆ ๊ฐœ๋ฐœ ๋ธ”๋กœ๊ทธ ์ž…๋‹ˆ๋‹ค.

GitHubMediumTwitterFacebook