오늘은 복사에 대해서 적어볼까 합니다.
자바스크립트에서 복사는 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.stringify
와 JSON.parse
라는 메소드를 이용하면
객체/배열을 문자열로, 그리고 문자열을 객체/배열로 바꾸어 줄 수 있습니다.
깊은복사를 손쉽게 도와주는 라이브러리 Lodash를 이용해보세요!
Lodash 라이브러리 바로가기