μ€‘μ²©λœ 객체λ₯Ό κ°€μ§„ 객체의 κΉŠμ€ 볡사 ν•˜λŠ” 방법

ν‚€-κ°’ 쌍이 μ—¬λŸ¬ 개인 객체가 μžˆμŠ΅λ‹ˆλ‹€. λ¬Έμ œλŠ” 객체가 μ™„μ „ν•˜μ§€ μ•Šλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. 이 λ¬Έμ œλŠ” 객체에 기쑴데이터가 μžˆλŠ” μƒνƒœμ—μ„œ μƒˆλ‘œμš΄ ν•„λ“œλ₯Ό μΆ”κ°€ν•˜λŠ” κ²½μš°λ‚˜ μ™ΈλΆ€ APIμ—μ„œ 데이터λ₯Ό 가져와 ν˜„μž¬ 데이터 λͺ¨λΈμ— μ—°κ²°ν•΄μ•Ό ν•˜λŠ” κ²½μš°μ— 자주 λ°œμƒν•©λ‹ˆλ‹€. μ–΄λŠ μͺ½μ΄λ“  λ¬Έμ œκ°€ λ˜λŠ” 뢀뢄은 κ°™μŠ΅λ‹ˆλ‹€. μƒˆλ‘œμš΄ ν•„λ“œ λ˜λŠ” λ°μ΄ν„°λ‘œ μ±„μ›Œμ§€μ§€ μ•ŠλŠ” λ‚˜λ¨Έμ§€ 뢀뢄을 κΈ°λ³Έκ°’ 객체둜 μ±„μ›Œμ•Ό ν•œλ‹€λŠ” μ μž…λ‹ˆλ‹€.

기본값을 μ„€μ •ν•˜λ©΄μ„œ μ›λž˜μ˜ 데이터λ₯Ό μœ μ§€ν•˜λŠ” μƒˆλ‘œμš΄ 객체λ₯Ό μƒμ„±ν•˜λ €λ©΄ μ–΄λ–»κ²Œ ν•΄μ•Ό ν• κΉŒμš”?
λ‹Ήμ—°νžˆ λΆ€μˆ˜ νš¨κ³Όλ‚˜ μ‘°μž‘μ€ λ°œμƒν•˜μ§€ μ•Šμ•„μ•Ό ν•©λ‹ˆλ‹€.

πŸ“ Object.assign()을 μ΄μš©ν•œ 값이 μ€‘μ²©λ˜μ§€ μ•Šμ€ 객체의 볡사 (Shallow Copy)

const default = {
  author:'',
  title:'',
  year:2017,
  rating:null
};

const book = {
  author : 'joe Morgan',
  title : 'Simplifying JavaScript'
};

const updated = Object.assign({}, defaults, book);
console.log(updated);

//{ 
//  author : 'joe Morgan',
//  title : 'Simplifying JavaScript,
//  year:2017,
//  rating:null
//}
μœ„μ˜ μ½”λ“œλŠ” defaults와 book 객체λ₯Ό λ³‘ν•©ν•˜μ—¬ 얕은 볡사λ₯Ό μˆ˜ν–‰ν•©λ‹ˆλ‹€. ν•˜μ§€λ§Œ details κ°μ²΄λŠ” μ°Έμ‘° 관계가 μœ μ§€λ˜λ―€λ‘œ shallowCopy 객체λ₯Ό μˆ˜μ •ν•˜λ©΄ defaultsλ‚˜ book에도 영ν–₯을 λ―ΈμΉ  수 μžˆμŠ΅λ‹ˆλ‹€.

πŸ“ Object.assign()을 μ΄μš©ν•œ 값이 μ€‘μ²©λœ 객체의 볡사 (Deep Copy)

μ€‘μ²©λœ 객체가 μžˆλŠ” κ²½μš°μ— Object.assign()을 μ΄μš©ν•΄μ„œ λ³΅μ‚¬ν•˜λ„λ‘ ν•˜λ©΄ λͺ¨λ“  것을 κ°±μ‹ ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
const defaultEmployee = {
    name : {
          first : '',
          last : ''
        }
    years : 0,
};
const employee = Object.assign({}, defaultEmployee);
μœ„μ˜ μ½”λ“œμ—μ„œ name 속성은 볡사 ν• μˆ˜ μ—†μŠ΅λ‹ˆλ‹€. μ‹€μ œλ‘œ ν‚€ name에 ν• λ‹Ήλœ 독립적인 객체에 λŒ€ν•΄ 참쑰만 볡사 λ©λ‹ˆλ‹€. μ€‘μ²©λœ κ°μ²΄λŠ” ν•΄λ‹Ή 객체λ₯Ό λ‹΄κ³  μžˆλŠ” 객체와 λ…λ¦½μ μœΌλ‘œ μ‘΄μž¬ν•©λ‹ˆλ‹€.

μ€‘μ²©λœ 객체λ₯Ό λ‹΄κ³  μžˆλŠ” 객체가 κ°€μ§€κ³  μžˆλŠ” 것은 μ€‘μ²©λœ 객체에 λŒ€ν•œ μ°Έμ‘° λΏμž…λ‹ˆλ‹€. 참쑰에 λŒ€ν•œ λ³΅μ‚¬λ§ŒμœΌλ‘œλŠ” μ€‘μ²©λœ 객체에 κΉŠμ€ 볡사λ₯Ό μ μš©ν•  수 μ—†μŠ΅λ‹ˆλ‹€. 단지 참쑰의 μœ„μΉ˜λ₯Ό λ³΅μ‚¬ν•˜λŠ” 것에 뢈과 ν•©λ‹ˆλ‹€.

λ”°λΌμ„œ 원본 객체 λ˜λŠ” λ³΅μ‚¬ν•œ 객체 쀑 μ–΄λ””μ„œλΌλ„ μ€‘μ²©λœ 객체의 값을 λ³€κ²½ν•˜λ©΄ 원본 객체와 λ³΅μ‚¬ν•œ 객체 λͺ¨λ‘ λ³€κ²½λ©λ‹ˆλ‹€.
const defaultEmployee = {
  name : {
           first : '',
           last : ''
         }
  years : 0,
};

const employee2 = Object.assign(
  {},
    defaultEmployee,
    {
      name : Object.assign({} , defaultEmployee.name)
    }
);

πŸ“ Lodashλ₯Ό μ΄μš©ν•œ κΉŠμ€ 볡사 cloneDeep

Lodash λΌμ΄λΈŒλŸ¬λ¦¬λŠ” κΉŠμ€ 볡사λ₯Ό μˆ˜ν–‰ν•˜λŠ” cloneDeep λ©”μ„œλ“œλ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€. LodashλŠ” 일반적인 μœ ν‹Έλ¦¬ν‹° ν•¨μˆ˜λ“€μ„ λͺ¨μ•„놓은 λΌμ΄λΈŒλŸ¬λ¦¬λ‘œμ„œ, κΉŠμ€ 볡사λ₯Ό μ‰½κ²Œ μ²˜λ¦¬ν•  수 있게 λ„μ™€μ€λ‹ˆλ‹€.
const _ = require('lodash');

const defaults = {
  author: '',
  title: '',
  details: {
    pages: 0,
    language: ''
  }
};

const book = {
  author: 'John Doe',
  title: 'Sample Book',
  details: {
    pages: 200,
    language: 'English'
  }
};

const deepCopyResult = _.cloneDeep(defaults);
_.merge(deepCopyResult, book);

console.log(deepCopyResult);
cloneDeep ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λ©΄ μ€‘μ²©λœ κ°μ²΄κΉŒμ§€ κΉŠμ€ 볡사가 μ΄λ£¨μ–΄μ§‘λ‹ˆλ‹€. 이후 merge ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ 두 객체λ₯Ό 병합할 수 μžˆμŠ΅λ‹ˆλ‹€.

πŸ“ JSON.stringify() μ΄μš©ν•œ κΉŠμ€ 볡사 cloneDeep

JSON.stringify()와 JSON.parse()λ₯Ό μ΄μš©ν•˜μ—¬ 객체λ₯Ό λ¬Έμžμ—΄λ‘œ λ³€ν™˜ν•˜κ³  λ‹€μ‹œ νŒŒμ‹±ν•˜μ—¬ κΉŠμ€ 볡사λ₯Ό μˆ˜ν–‰ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 단, 이 방법은 ν•¨μˆ˜λ‚˜ νŠΉλ³„ν•œ νƒ€μž…μ˜ κ°μ²΄μ—λŠ” μ μš©λ˜μ§€ μ•Šμ„ 수 μžˆμŠ΅λ‹ˆλ‹€.
const originalObject = {
  nestedObject: {
    key: 'value'
  },
  otherKey: 'otherValue'
};

const deepCopy = JSON.parse(JSON.stringify(originalObject));
        
ν•˜μ§€λ§Œ 이방법은 μ‚¬μš©ν•˜κΈ°λŠ” μ‰½μ§€λ§Œ λ‹€λ₯Έ 방법에비해 μ•„μ£Ό λŠλ¦¬λ‹€κ³  μ•Œλ €μ Έ μžˆμŠ΅λ‹ˆλ‹€.