본문 바로가기
핀테크 서비스 프론트엔드 개발자 취업 완성 2기/JS

[JS] 데이터 - 얕은복사(Shallow copy) & 깊은 복사(Deep copy)

by flyda 2022. 4. 26.

얕은복사(Shallow copy) & 깊은 복사(Deep copy)

참조형 데이터에 할당연산자를 사용했을 때 나타날 수 있는 문제

const user = {
  name: 'Flyda',
  age: 85,
  emails: ['dskjskjdad@gmail.com']
}

const copyUser = user 
console.log(copyUser === user)//true

user.age = 22
console.log('user', user)//user {name: 'Flyda', age: 22, emails:  ['dskjskjdad@gmail.com']}
console.log('copyUser', copyUser) //copyUser {name: 'Flyda', age: 22, emails:  ['dskjskjdad@gmail.com']}

얕은 복사

  • Object.assign을 사용해서 복사하는 방법
    const user1 = {
    name: 'Flyda',
    age: 85,
    emails: ['dskjskjdad@gmail.com']
    }
    const copyUser1 = Object.assign({},user1)
    console.log(copyUser1 === user1)//false
    

user1.age = 22
console.log('user', user1)//user {name: 'Flyda', age: 22, emails: ['dskjskjdad@gmail.com']}
console.log('copyUser', copyUser1) //copyUser {name: 'Flyda', age: 85, emails: ['dskjskjdad@gmail.com']}


- 전개연산자를 사용해서 복사하는 방법 
```js
const user = {
  name: 'Flyda',
  age: 85,
  emails: ['dskjskjdad@gmail.com']
}

const copyUser = {...user}
console.log(copyUser === user)//false

user.age = 22
console.log('user', user)//user {name: 'Flyda', age: 22, emails:  ['dskjskjdad@gmail.com']}
console.log('copyUser', copyUser) //copyUser {name: 'Flyda', age: 85, emails:  ['dskjskjdad@gmail.com']}

얕은 복사에서 나타날 수 있는 문제점

const user = {
  name: 'Flyda',
  age: 85,
  emails: ['dskjskjdad@gmail.com']
}

const copyUser = {...user}
console.log(copyUser === user)//false

user.age = 22
console.log('user', user)//user {name: 'Flyda', age: 22, emails:  ['dskjskjdad@gmail.com']}
console.log('copyUser', copyUser) //copyUser {name: 'Flyda', age: 85, emails:  ['dskjskjdad@gmail.com']}

console.log('-----')
console.log('-----')

//객체 데이터인 user는 복사했지만 user 안에 배열데이터인 emails는 같은 메모리주소를 여전히 공유하고 있음. 
user.emails.push('neo@naver.com')
console.log(user.emails === copyUser.emails) //true

console.log('user', user)//user {name: 'Flyda', age: 22, emails:  ['dskjskjdad@gmail.com', 'neo@naver.com']}
console.log('copyUser', copyUser) //copyUser {name: 'Flyda', age: 85, emails:  ['dskjskjdad@gmail.com', 'neo@naver.com']}

객체 데이터인 user는 복사했지만 user 안에 배열데이터인 emails는 같은 메모리주소를 여전히 공유하고 있어 emails가 user와 copyUser에서 보두 변하는 것을 볼 수 있다.


깊은 복사

lodash의 도움을 받을 예정!!

콘솔창에서 npm i lodash를 입력하기!! 개발에서만 쓸 것이 아니기 때문에 -D플레그는 사용하지 않음!
그리고 사용을 원하는 js 파일에서 import _ from 'lodash' 를 입력하고 사용하면 된다.

나는 콘솔창에서 npm으로 시작하는 것이 좀 귀찮아서 그냥 index.html파일에 cdn 을 넣었다.

  <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

lodash를 사용하여 깊은 복사를 구현한 코드는 다음과 같다

const user = {
  name: 'Flyda',
  age: 85,
  emails: ['dskjskjdad@gmail.com']
}

const copyUser = _.cloneDeep(user)
console.log(copyUser === user)//false

user.age = 22
console.log('user', user)//user {name: 'Flyda', age: 22, emails:  ['dskjskjdad@gmail.com']}
console.log('copyUser', copyUser) //copyUser {name: 'Flyda', age: 85, emails:  ['dskjskjdad@gmail.com']}

console.log('-----')
console.log('-----')


user.emails.push('neo@naver.com')
console.log(user.emails === copyUser.emails) //false

console.log('user', user)//user {name: 'Flyda', age: 22, emails:  ['dskjskjdad@gmail.com', 'neo@naver.com']}
console.log('copyUser', copyUser) //copyUser {name: 'Flyda', age: 85, emails:  ['dskjskjdad@gmail.com']}

참조형 데이터를 복사할 때, 그냥 단순한 객체 구조라면 얕은 복사를 활용하면 된다. 하지만 복사하려는 객체 데이터 안에 또다른 참조형 데이터가 있는 경우 lodash의 도움을 받아서 cloneDeep을 통해서 깊은 복사를 할 수 있다. (그냥 js로 구현하려면 복잡하기 때문에 팩키지의 도움을 받을 수 있다. )

댓글