Shallow Copy & Deep Copy

M_yeon·2022년 9월 24일
0

javascript

목록 보기
5/15
post-thumbnail

오늘은 복사에 대해서 적어볼까 합니다.
자바스크립트에서 복사는 2가지 종류가 있는데,

Shallow Copy = 얕은복사
Deep Copy = 깊은복사

얕은복사는 주소값을 복사합니다. 즉, 참조하고 있는 실제값은 같습니다.
깊은복사는 실제값을 새로운 메모리 공간에 복사합니다. 즉, 실제값이 다릅니다.

let child1 = {
	name: "철수",
	age: 8,
	school: "다람쥐초등학교"
}
let child2 = child1

child2 // {name: '철수', age: 8, school: '다람쥐초등학교'}

위처럼 child1 을 새로운 변수 child2에 복사합니다
그 후에 데이터를 아래 처럼 변경을 해보죠

child2.name = "영희"

child1 // {name: '영희', age: 8, school: '다람쥐초등학교'}
child2 // {name: '영희', age: 8, school: '다람쥐초등학교'}

이렇게 객체타입의 데이터를 새로운 변수 child2 = child1 이라고 복사를 하게되면 이것은 얕은복사

즉 참조하는 실제값은 같다는것이고 이렇게 되면 원본의 데이터도 같이 변합니다.
여기에서 {}가 주소를 뜻합니다.
그래서 스프레드연산자를 통해 새로운 주소를 만들고 가져와야하는데 아래처럼 작성하면 됩니다.

 let profile1 = {
    name: "철수",
    age: 8,
    school: "공룡초등학교",
    hobby: {
        first: "수영",
        second: "프로그래밍"
    }
}

let profile2 = {
    ...profile1
}

profile1.name = "영희"

profile1 // {name: '영희', age: 8, school: '공룡초등학교', hobby: {…}}
profile2 // {name: '철수', age: 8, school: '공룡초등학교', hobby: {…}}

하지만 위처럼 객체안에 객체가 있을경우 스프레드 연산자를 통해서 school까지는 가져올 수 있지만 hobby까지 가져오기에는 무리입니다.

얕은 복사는 depth 1의 깊이를 가진 데이터까지는 복사할 수 있지만,
depth 2 이상의 깊이를 가진 데이터는 복사하지 못합니다.

여기에서 스프레드연산자를 통해 hobby이전까지 가져오는것을 얕은복사 라고 합니다.

🍭 중첩 객체 복사 with 스프레드 연산자
스프레드 연산자를 이용한 복사도 만능은 아닙니다.
객체 안에 객체가 값으로 들어가 있는 경우에는 제대로 복사가 되지 않습니다.


깊은 복사

그렇다면 어떻게 depth 2 이상의 깊이를 가진 데이터를 복사하여 새로운 객체를 만들 수 있을까요?

객체를 문자열의 형태로 바꾸고, 그 문자열을 다시 객체로 바꾸어 새로운 변수에 담아주면 됩니다.

JSON.stringifyJSON.parse라는 메소드를 이용하면

객체/배열을 문자열로, 그리고 문자열을 객체/배열로 바꾸어 줄 수 있습니다.

또한❗️완벽한 Deep copy를 위한 다른 방법

  • 재귀적으로 깊은 복사를 수행
  • Lodash의 cloneDeep 함수 사용
  • JSON.parse()와 JSON.stringify()함수 사용

깊은복사를 손쉽게 도와주는 라이브러리 Lodash를 이용해보세요!
Lodash 라이브러리 바로가기

2개의 댓글