자바스크립트의 객체를 깊은 복사하는 방법에는 여러 가지가 있다.
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