우리는 코딩을 하다보면 특정 객체를 복사해서 재할당한 뒤 기존 객체와 비교를 하는 등의 일이 생긴다. 하지만 앞서 포스팅한 내용들을 기반으로 볼 때, 아래 코드와 같이 복사한 객체를 바꾸면 기존 객체도 함께 바뀌는 것을 확인할 수 있다.
obj1 = {
x: 3,
arr: [3, 4, 5]
}
obj2 = obj1
obj2.x = 5
console.log(obj1.x) //5
console.log(obj2.x) //5
이에 우리는 참조형 데이터를 복사할 필요가 있다. 복사에는 얕은 복사, 깊은 복사 두 종류가 있다.
바로 아래 단계의 값만 복사하는 것이다.
const copyObj = function(obj) {
let result = {}
for(let key in obj) {
result[key] = obj[key]
}
return result
}
위 함수를 사용하여 객체를 얕은 복사할 수 있다.
const array = [1, 3, 5, 7, 9]
const copiedArray = [...array]
배열의 경우 spread 문법을 통해 얕은 복사할 수 있다.
얕은 복사는 참조형 데이터에 중첩된 참조형 데이터가 없을 때, 즉 객체의 모든 프로퍼티 값이 기본형 데이터일 경우 가능하다.
그렇다면 중첩된 참조형 데이터를 복사하려면 어떻게 해야할까?
내부 모든 값을 복사하는 것이다.
const copyDeepObj = function(obj) {
let result = {}
if(typeof obj === 'object' && obj !== null) {
for(let key in obj) {
result[key] = copyDeepObj(obj[key])
}
} else result = obj
return result
}
위 함수를 사용하여 객체를 깊은 복사할 수 있다.
let copyObjByJSON = function(obj) {
return JSON.parse(JSON.stringify(obj))
}
깊은 복사하는 함수를 따로 만들 필요 없이 객체를 JSON문법으로 표현된 문자열로 바꿨다가 JSON객체로 바꾸면 된다. 하지만 이 방법은 JSON으로 변경할 수 없는 프로퍼티(함수 등)는 무시한다.
이 외에도 immutable.js, baobab.js 등의 라이브러리를 사용해도 된다.