객체 / 배열 깊은 복사, 얕은 복사(+lodash)

huni_·2022년 7월 6일
0

React

목록 보기
26/57
post-thumbnail

객체나 배열을 복사할 때, 두 가지 개념이 존재합니다.

얕은 복사(Shallow Copy) / 깊은 복사(Deep Copy) 입니다.

얕은 복사주소값을 복사합니다. 즉, 원본의 값이나 복사된 값이 변경될 경우 두 값 모두 변경 됩니다.

위와 같이 profile을 복사한 friendprofileprofilename을 변경하니 함께 name이 변경되는 것을 확인 할 수 있습니다.

깊은 복사얕은 복사와 달리 주소값을 복사하는 것이 아닌, 전부를 복사해 새 주소에 담아주어 참조를 공유하지 않게 됩니다.

String, Number, Boolean은 모두 값을 복사합니다.
하지만 객체배열은 모두 주소에 저장하고 복사를 합니다.
그렇기 때문에 값을 변경을 하면 원본과 복사본 모두 변경이 되게 되는 것입니다.

위 사진처럼 주소를 만드는 방법은

let profile = {
	name: "철수",
  	age: 8,
  	school: "다람쥐초등학교"
}
// 이렇게 중괄호나 대괄호를 사용할 시에 새로운 주소가 만들어집니다.

사실 복사는 없습니다. 유사하게 사용하려면

let profile2 ={
 	name: profile.name,
  	age: profile.age,
  	school: prodile.school
}

이렇게 작성하면 됩니다.
통째로 복사는 불가합니다.

위 코드를 보다 쉽게 복사하는 방법이 무엇일까?

그래서 나온게 스프레드 연산자입니다. ...profile

let profile3 = {...profile}

알멩이만 복사합니다.

근데 여기서 문제가 있습니다.

let profile = {
	name: "철수",
  	age: 8,
  	school: "다람쥐초등학교",
  	hobby: {
    	hobby1: "수영",
      	hobby2: "게임"
    }
}
let profile2 = {
	...profile
}

이렇게 profile을 복사해서 prodile2를 만들었습니다. 여기서 profile.hobby.hobby1을 변경한다면 profile2는 변경이 안되겠죠?
하지만 변경이 됩니다... 그 이유는 hobby에 {}를 사용해서 객체를 생성했기 때문입니다.
위에서 말했듯이 {}를 사용하면 새로운 주소가 생성된다고 배웠습니다.
그래서 같은 주소이기 때문에 hobby안에 있는 hobby1이 똑같이 변경이 됩니다.
이런 현상때문에 ...스프레드 연산자는 얕은 복사(Shallow Copy)라고 합니다.

깊은 복사의 방법으로 전체를 문자열로 만든 뒤 JSON.stringfy() , 그 문자열을 객체로 돌리는 방법 JSON.parse() 이 있습니다.
JSON.parse()를 해서 나온 객체는 새로운 객체입니다.

JSON.stringfy(profile)
// 객체를 문자열로 만든다.
JSON.parse("{\"name\"}": \"철수\")
// 완전히 새로운 객체를 만든다.
JSON.parse(JSON.stringify(profile))
// 객체를 문자열로 변경 후 새로운 객체를 만든다.
let profile2 = JSON.parse(JSON.stringify(profile))
// 새로운 객체를 만든 것을 profile2 에 담습니다.

위의 JSON.parse(JSON.stringfy(profile))myfriendprofile 변수에 담아주면 되겠죠?
하지만 위의 방식들은 속도가 느리다는 단점을 갖고 있습니다. 이를 개선 시킨 lodash 라는 라이브러리가 있습니다.

lodash 안에 cloneDeep이라는 깊은 복사가 있습니다.

lodash는 보통 를 사용해서 import합니다.
ex)
.cloneDeep()


profile
FrontEnd Developer

0개의 댓글