본 글은 정재남 님의 저서 <코어 자바스크립트>를 읽고 정리한 내용입니다.
이전 포스팅에서 객체를 복사하는 몇 가지 방법에 대해 알아보았다. 하지만 이 방법들은 객체의 깊이
가 1
인 경우 (중첩 객체가 아닌 경우)에만 깊은 복사
가 된다. 그렇기 때문에 중첩된 객체
에서 참조형 데이터
가 저장된 프로퍼티
를 복사할 때는 그 주소값이 저장되므로 결과적으로 얕은 복사가 되는 셈이다.
이번 포스팅에서는 중첩 객체
를 deep copy
하는 두 가지
방법을 알아보려고 한다.
첫 번째 방법은 재귀적 호출
을 이용한 방법이다.
var copyObjectDeep = function (target) {
var result = {};
// null의 type도 object이기 때문에 target !== null 조건 추가
if (typeof target === 'object' && target !== null) {
for (var prop in target) {
result[prop] = copyObjectDeep(target[prop]);
}
} else {
result = target;
}
return result;
}
위 방법은 target
이 객체
인 경우에 내부 프로퍼티들을 순회하면서 copyObjectDeep
함수를 재귀적으로 호출한다.
객체가 아닌 경우에는 target
을 그대로 지정한다.
이 함수를 사용해 객체를 복사한 후에는 원본
과 사본
이 전혀 다른 객체
를 참조
하게 된다. 이제는 어느 쪽의 프로퍼티를 저장하더라도 서로에게 영향을 주지 않는다.
단, 위 코드의 경우 프로퍼티가 배열인 경우 객체로 변환되어 복사되므로 수정이 필요하다.
getter와 setter도 복사되지 않는다.
재귀 호출보다 더 간단한 방법이 있다. 바로 JSON
을 활용한 방법이다.
원리는 객체를 JSON문법으로 표현된 문자열로 전환했다가 다시 JSON객체로 바꾸는 것이다. 이 방법은 단순하지만 아주 잘 작동한다. 다만 메서드(함수)나 숨겨진 프로퍼티인 __proto__
나 getter/setter
등과 같이 JSON으로 변경할 수 없는 프로퍼티들은 모두 무시한다.
httpRequest
로 받은 데이터를 저장한 객체를 복사할 때 유용할 수 있다.
var copyObjectViaJSON = function (target) {
return JSON.parse(JSON.stringify(target));
};
let obj = {
a: 1,
b: {
c:1,
d:2,
}
}
let newObj = copyObjectViaJSON(obj);
newObj.b.c = 100;
console.log(obj); // { a: 1, b: { c: 1, d: 2 } }
console.log(newObj); // { a: 1, b: { c: 100, d: 2 } }
Node.js에서 Lodash를 사용하려면 우선 Pacakge를 다운로드 받아야 한다.
npm i lodash
const lodash = require('lodash');
const object = {
a: "a",
number: {
one: 1,
two: 2,
},
arr: [1, 2, [3, 4]],
};
const object2 = lodash.cloneDeep(object);
object.number.one = 1000;
object.number.two = 2000;
console.log(object); // { a: 'a', number: { one: 1000, two: 2000 }, arr: [ 1, 2, [ 3, 4 ] ] }
console.log(object2); // { a: 'a', number: { one: 1, two: 2 }, arr: [ 1, 2, [ 3, 4 ] ] }