얕은 복사(Shallow Copy)
깊은 복사(Deep Copy)
복사면 복사지 무슨 차이일까? 😡😡
let aaa = "철수"
let bbb = aaa
bbb = aaa "철수
// bbb를 영희로 재할당한다면?
bbb = "영희"
aaa = "철수"
보통 이런 식으로 데이터가 복사되고, 복사본을 바꿀 경우 원본의 값은 변화없음.
그런데 만약에 객체를 이런 식으로 복사한다면?
let child1 = {
name: "철수",
age: 8,
school: "다람쥐초등학교"
}
let child2 = child1
child2 = {name: "철수", age: 8, school: "다람쥐 초등학교"}
// child2의 객체를 변경한다면?
child2.name = "영희"
child1 // {name: '영희', age: 8, school: '다람쥐초등학교'}
child2 // {name: '영희', age: 8, school: '다람쥐초등학교'}
💡객체와 배열의 경우는 값 자체가 바뀌는 것이 아니라 "주소"가 저장되기 때문이다.
그러면 어떻게 하면 이런 문제 없이 객체를 복사할까?
복사가 아닌, 원본 객체와 같은 값을 가진 새로운 객체를 만드는 방법
// child3에 child2 복사
let child3 = {
name: child2.name,
age: child2.age,
school: child2.schhol
}
//이러할 경우 child3의 값을 변경해도 child2의 값이 변하지 않음.
child3.name = "훈이"
child3 // {name: '훈이', age: 8, school: '다람쥐초등학교'}
child2 // {name: '영희', age: 8, school: '다람쥐초등학교'}
위와 같이 변수가 가리키는 주소값이 같은 주소값을 가리킬 때
얕은 복사가 이루어진다고 한다
객체를 복사할 때 일일이 적는 것은 매우 번거롭기 때문에
객체의 데이터를 뿌려주는 연산자
let child3 = {
name: child2.name,
age: child2.age,
school: child2.schhol
}
//위와 같이 쓰는 것을 스프레드 연산자를 통해 아래와 같이 나타낼 수 있음
let child3 = {
...child2
}
만약 객체안에 객체가 있으면?
let child2 = {
name: "철수",
age: 8,
school: "다람쥐 초등학교"
hobby: {
hobby1: "축구",
hobby2: "농구"
}
}
let child3 = {
...child2
}
// 이런식으로 쓸 경우에는 hobby가 복사가 제대로 안됨(child3의 hobby1을 변경하면 child2도 같이 변경)
// 위와 같은 경우에는
let child3 = {
...child2,
hobby:{...child2.hobby}
}
※ 💡위처럼 스프레드 연산자는 depth1 까지의 값에서만 깊은복사가 실행된다.
그렇다면 어떻게 객체는 depth2 이상의 깊은복사를 할 수 있을까?
객체를 문자열로 바꾸고 다시 문자열을 객체로 바꾸어 변수에 담아주면 된다.
☑️
객체 -> 문자열 -> 객체
객체를 문자열로 바꾸어주는
📌 JSON.stringify문자열을 객체로 바꾸어주는
📌 JSON.parse
JSON.stringify(profile1)
// `{"name":"철수","age":8,"school":"공룡초등학교","hobby":{"first":"수영","second":"농구"}}`
JSON.parse(JSON.stringify(profile1))
// {name: '철수', age: 8, school: '공룡초등학교', hobby: {first: '수영', second: '농구'}}
객체를 복사할 때 깊은복사를 도와주는 라이브러리
lodash에서 제공하는 _.cloneDeep(value)를 사용하면 쉽게 깊은복사 가능
📌 Lodash Docs: https://lodash.com/docs/4.17.15
검색해보다가 댓글드립니다! 스프레드 연산자는 얕은복사 아닌가요?