자바스크립트의 객체를 깊은 복사하는 방법에는 여러 가지가 있다.
for
문과 재귀함수
의 조합JSON
객체의 stringify()
, parse()
메서드structuredClone()
lodash
의 cloneDeep()
순서대로 알아보도록 하자.
for
문을 돌려서 프로퍼티의 값이 Object
라면 재귀적으로 함수를 호출하여 새로운 객체{}
를 만들어서 키를 할당하는 방식이다.
const objectWillCopied = {
a: 1,
b: { c: 2 }
};
function deepCopyObj(original) {
// 들어온 값이 null 또는 object 타입이 아니라면 그대로 반환
if(original === null || typeof original !== 'object') return original;
// 객체인지 배열인지 검사 후 객체라면 {}, 배열이라면 []
const copied = Array.isArray(original) ? [] : {};
for (let key in original) {
copied[key] = deepCopyObj(original[key]);
}
return copied;
}
let copiedObj = deepCopyObj(objectWillCopied);
copiedObj.b.c = 3
console.log(objectWillCopied.b.c === copiedObj.b.c) //false
내장 객체 JSON
의 메서드를 사용한 깊은 복사 방법은 그다지 어렵지 않다.
복사하고 싶은 객체를 JSON.stringify()
를 사용하여 객체
를 문자열
로 바꾼다.
이렇게 메모리상에 존재하는 객체
를 문자열
로 변환하는 것을 직렬화(Serialization)
라고 한다. 이 과정에서 원본 객체와의 참조가 모두 끊어진다.
직렬화
된 문자열(객체였던 것)을 JSON.parse()
를 사용하여 객체
로 바꾼다.
이렇게 다시 문자열
을 객체
로 변환하는 것을 역직렬화(Deserialization)
또는 파싱(parsing)
이라고 한다.
structuredClone
보다 느리다.undefined
를 반환한다.const objectWillCopied = {
a: 1,
b: { c: 2 }
};
const stringifiedObject = JSON.stringify(objectWillCopied); // 직렬화
const copiedObj = JSON.parse(stringifiedObject); // 역직렬화 또는 파싱
copiedObj.b.c = 3;
console.log(objectWillCopied.b.c === copiedObj.b.c); // false
structuredClone
은 수많은 HTML DOM API
중 하나로, structured clone 알고리즘
을 이용하여 주어진 값의 깊은 복사본을 생성해주는 API이다.
JSON
객체의 메서드를 이용한 복사의 단점이 보완되는 부분이 존재한다.RegExp
, Blob
, File
와 FileList
, ImageData
객체들도 복사할 수 있다.DOM API
라서 Node.js
환경에서 작동하지 않는다.const objectWillCopied = {
a: 1,
b: { c: 2 }
};
const copiedObj = structuredClone(objectWillCopied);
copiedObj.b.c = 3;
console.log(objectWillCopied.b.c === copiedObj.b.c); // false
lodash
는 객체나 배열 등의 자료 구조를 쉽게 변환하여 사용할 수 있게 도와주는 자바스크립트 라이브러리이다.
lodash
의 설치는 홈페이지에서 참고할 수 있다.
lodash
의 수많은 메서드들 중에 cloneDeep
메서드는 객체의 깊은 복사를 수행하는 함수이다.
const objectWillCopied = {
a: 1,
b: { c: 2 },
};
const copied = _.cloneDeep(objectWillCopied);
copied.b.c = 3;
console.log(copied.b.c === objectWillCopied.b.c); // false