[JavaScript] Shallow Copy & Deep Copy

쑰혜인·2022λ…„ 8μ›” 21일
post-thumbnail

πŸ“Œ 얕은 볡사(Shallow copy)

  • 얕은 λ³΅μ‚¬λŠ” μ£Όμ†Œ 값을 λ³΅μ‚¬ν•œλ‹€. 즉, κ°’ 자체λ₯Ό λ³΅μ‚¬ν•˜λŠ” 것이 μ•„λ‹ˆλΌ μ£Όμ†Œκ°’μ„ λ³΅μ‚¬ν•˜μ—¬ 같은 λ©”λͺ¨λ¦¬λ₯Ό 가리킨닀.
  • μƒˆλ‘œμš΄ μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— κΉŠμ€ 볡사(Deep Copy)보닀 μƒλŒ€μ μœΌλ‘œ λ°”λ₯΄λ‹€.

μ•„λž˜μ˜ μ˜ˆμ‹œλ₯Ό μ‚΄νŽ΄λ³΄μž. 얕은 볡사 μ—μ„œλŠ” 객체(배열도 κ°€λŠ₯)λ₯Ό μŠ€ν”„λ ˆλ“œ μ—°μ‚°μž(...)λ₯Ό ν™œμš©ν•˜μ—¬ λ³΅μ‚¬ν•œλ‹€.

let profile = {
	 name : "철수",
	 age : 12,
	 school : "λ‹€λžŒμ₯μ΄ˆλ“±ν•™κ΅"
}

let profile2 = {...profile}      //μŠ€ν”„λ ˆλ“œ μ—°μ‚°μžλ₯Ό μ‚¬μš©
profile.name = "영희"

profile2        // {name: '철수', age: 12, school: 'λ‹€λžŒμ₯μ΄ˆλ“±ν•™κ΅'}
profile         // {name: '영희', age: 12, school: 'λ‹€λžŒμ₯μ΄ˆλ“±ν•™κ΅'}

profileμ—λŠ” 철수의 정보가 λ“€μ–΄μžˆλ‹€. 이 profile을 μŠ€ν”„λ ˆλ“œ μ—°μ‚°μžλ₯Ό μ΄μš©ν•˜μ—¬ profile2에 볡사해쀀 ν›„ 원본(profile)의 값을 λ³€κ²½ν•˜μ˜€μ„ λ•Œ, μ‚¬λ³Έμ—λŠ” 영ν–₯을 λΌμΉ˜μ§€ μ•ŠλŠ” 것을 확인할 수 μžˆλ‹€.

그런데 μ—¬κΈ°μ„œ λ¬Έμ œμ μ€, 얕은 λ³΅μ‚¬λ‘œλŠ” 객체 μ•ˆμ˜ 객체(depth 2 이상)κΉŒμ§€ 볡사가 λ˜μ§€ μ•ŠλŠ”λ‹€.

let profile = {
    name : "철수",
    age : 12,
    school : "λ‹€λžŒμ₯μ΄ˆλ“±ν•™κ΅", 
    hobby: {
        hobby1: "수영",
        hobby2: "μžμ „κ±°"
    }
}

let profile2 = {...profile}

/* depth 1인 값을 λ³€κ²½ν•˜κΈ° */
profile.name = "영희"
profile
// {name: '영희', age: 12, school: 'λ‹€λžŒμ₯μ΄ˆλ“±ν•™κ΅', hobby: {…}}age: 12hobby: {hobby1: '수영', hobby2: 'μžμ „κ±°'}name: "영희"school: "λ‹€λžŒμ₯μ΄ˆλ“±ν•™κ΅"[[Prototype]]: Object
profile2
// {name: '철수', age: 12, school: 'λ‹€λžŒμ₯μ΄ˆλ“±ν•™κ΅', hobby: {…}}age: 12hobby: {hobby1: '수영', hobby2: 'μžμ „κ±°'}name: "철수"school: "λ‹€λžŒμ₯μ΄ˆλ“±ν•™κ΅"[[Prototype]]: Object


/* depth 2인 값을 λ³€κ²½ν•˜κΈ° */
profile2.hobby.hobby1 = "잠자기"
profile2
// {name: '철수', age: 12, school: 'λ‹€λžŒμ₯μ΄ˆλ“±ν•™κ΅', hobby: {…}}age: 12hobby: {hobby1: '잠자기', hobby2: 'μžμ „κ±°'}name: "철수"school: "λ‹€λžŒμ₯μ΄ˆλ“±ν•™κ΅"[[Prototype]]: Object
profile
// {name: '철수', age: 12, school: 'λ‹€λžŒμ₯μ΄ˆλ“±ν•™κ΅', hobby: {…}}age: 12hobby: {hobby1: '잠자기', hobby2: 'μžμ „κ±°'}name: "철수"school: "λ‹€λžŒμ₯μ΄ˆλ“±ν•™κ΅"[[Prototype]]: Object

μœ„μ˜ μ˜ˆμ‹œλ₯Ό 보면 depthκ°€ 2인 사본(profile2)의 hobby객체 μ•ˆμ˜ hobby1값을 λ³€κ²½ν•˜μ˜€μ„ λ•Œ, μ›λ³Έμ˜ hobby1에도 영ν–₯을 λΌμΉ˜λŠ” 것을 확인할 수 μžˆλ‹€. μ™„μ „νžˆ λΆ„λ¦¬λœ 객체λ₯Ό λ§Œλ“€ μˆ˜λŠ” μ—†μ„κΉŒ? 이 λ•Œ μ‚¬μš©ν•  수 μžˆλŠ” 것이 κΉŠμ€ 볡사(Deep copy)이닀.


πŸ“Œ κΉŠμ€ 볡사(Deep Copy)

  • κΉŠμ€ λ³΅μ‚¬λŠ” JSON(JavaScript Object Notation)을 μ‚¬μš©ν•œλ‹€.
let profile = {
    name : "철수",
    age : 12,
    school : "λ‹€λžŒμ₯μ΄ˆλ“±ν•™κ΅", 
    hobby: {
        hobby1: "수영",
        hobby2: "μžμ „κ±°"
    }
}

/* JSON을 μ΄μš©ν•˜μ—¬ 원본을 string으둜 λ°”κΏ”μ£ΌκΈ° - μ•„λž˜ κ²°κ³Όλ₯Ό 보면 μ•žλ’€λ‘œ ''κ°€ 뢙은 것을 확인할 수 μžˆλ‹€. */
JSON.stringify(profile)
// '{"name":"영희","age":12,"school":"λ‹€λžŒμ₯μ΄ˆλ“±ν•™κ΅","hobby":{"hobby1":"수영","hobby2":"μžμ „κ±°"}}'

/* JSON을 μ΄μš©ν•˜μ—¬ string으둜 λ³€κ²½λœ ꡬ문을 λΆ„μ„ν•˜μ—¬ μƒˆλ‘œμš΄ κ°’ ν˜Ήμ€ 객체둜 μƒμ„±ν•˜κΈ°(μ•„λž˜ 두 μ˜ˆμ‹œλŠ” 같은 μ˜ˆμ‹œ) */
profile2 = JSON.parse(JSON.stringify(profile))
profile3 = JSON.parse('{"name":"영희","age":12,"school":"λ‹€λžŒμ₯μ΄ˆλ“±ν•™κ΅","hobby":{"hobby1":"수영","hobby2":"μžμ „κ±°"}}')
// {name: '영희', age: 12, school: 'λ‹€λžŒμ₯μ΄ˆλ“±ν•™κ΅', hobby: {…}}

JSON의 parse()와 stringify()λ©”μ†Œλ“œλ₯Ό μ‚¬μš©ν•˜λ©΄ μƒˆλ‘œμš΄ μ£Όμ†Œκ°€ ν• λ‹Ήλ˜μ–΄ μ„œλ‘œ 영ν–₯을 λΌμΉ˜μ§€ μ•ŠλŠ”λ‹€. μ—¬κΈ°μ„œ JSON은 κ°μ²΄λŠ” μ•„λ‹ˆκ³  객체처럼 생긴 아이이닀.

[ + ] μΆ”κ°€μ μœΌλ‘œ LodashλΌλŠ” λΌμ΄λΈŒλŸ¬λ¦¬μ— cloneDeepμ΄λΌλŠ” λ©”μ†Œλ“œκ°€ μžˆλ‹€. cloneDeep()은 κΉŠμ€ 볡사λ₯Ό ν•΄μ£ΌλŠ” λ©”μ†Œλ“œμΈλ°, μœ„μ—μ„œ JSON의 parse()와 stringify()λ₯Ό μ‚¬μš©ν•œ 것보닀 νš¨μœ¨μ„±μ΄ 훨씬 μ’‹λ‹€.

profile
코딩은 μ—­μ‹œ 재밌ꡰ

0개의 λŒ“κΈ€