Front-End/JavaScript
[JavaScript] 깊은 복사, 얕은 복사
김당
2023. 3. 2. 00:15
JavaScript의 데이터 타입에는 2가지가 존재하며 타입에 따라 복사 방식이 다르다.
- 원시타입 : Number, String, Boolean, Undefined, Null 등
- 참조타입 : Object, Array 등
1. 깊은 복사 (Deep Copy)
: 독립적인 메모리에 객체의 실제 값만을 복사하여 생성하는 것
: 원시타입의 변수를 복사할 때는 복사된 값을 독립적인 다른 메모리에 할당하기 때문에 원래 값과 복사된 값이 서로 영향을 미치지 않는다.
: 깊은 복사된 객체는 객체 안에 객체가 있을 경우에도 원본과의 참조가 완전히 끊어진 객체를 말한다.
const a = 1;
let b = a;
b = 2
console.log(a); //1
console.log(b); //2
console.log(a === b); // false
복사 방법
JSON.stringify() : 객체를 인수로 받아 받은 객체를 문자열로 치환, 이때 원본 객체와의 참조가 모두 끊어진다.
JSON.parse() : 치환된 문자열을 다시 객체로 치환
*이 방법이 가장 간단하고 쉽지만 다른 방법에 비해 느리고, 객체가 function일 경우에는 undefined로 처리한다는 것이 단점이다.
const obj = {
a: 1,
b: { c: 2 },
func: function() {
return this.a;
}
};
const copyObj = JSON.parse(JSON.stringify(obj));
copyObj.b.c = 3;
console.log(obj); // { a: 1, b: { c: 2 }, func: function(){ return this.a; } }
console.log(copyObj); // { a: 1, b: { c: 3 } }
console.log(copyObj.func); //undefined
console.log(obj.b.c === copyObj.b.c); //false
2. 얕은 복사 (Shallow Copy)
: 객체의 참조값을 복사하는 것으로 기존 값과 복사된 값이 같은 참조를 가리키고 있는 것
: 참조타입의 변수를 복사할 때는 저장된 메모리의 주소를 복사하기 때문에 서로 영향을 미친다.
const a = {
one: 1,
two: 2,
};
let b = a;
b.one = 3;
console.log(a); // { one: 3, two: 2 }
console.log(b); // { one: 3, two: 2 }
복사 방법
Object.assign(생성할 객체, 복사할 객체);
: 객체 자체는 깊은 복사가 수행되지만 2차원 이상의 객체는 얕은 복사가 수행된다.
: 아래 예제에서는 1차원 객체인 obj를 깊은 복사하였기 때문에 copyObj라는 복사 객체를 생성 후 값을 변경해도 기존 obj의 값이 바뀌지 않고 서로 참조값이 다른 것을 확인할 수 있다.
const obj = { a: 1 };
const copyObj = Object.assign({}, obj);
copyObj.a = 2;
console.log(obj); // { a: 1 }
console.log(obj === copyObj); // false
: 아래 예제에서 복사된 객체 자체와 기존 객체 자체는 서로 다른 객체지만, 그 안에 들어가 있는 객체는 얕은 복사가 되어 기존 객체와 같은 참조값을 가리키고 있기 때문에 같은 참조값을 가리키는 것을 확인할 수 있다.
const obj = {
a: 1,
b: {
c: 2
}
}
const copyObj = Object.assign({}, obj);
copyObj.a = 2;
copyObj.b.c = 3;
console.log(obj); // { a: 1, b: { c: 3 } }
console.log(copyObj); //{ a: 2, b: { c: 3 } }
console.log(obj.a === copyObj.a); //false
console.log(obj.b.c === copyObj.b.c); // true
전개연산자(Spread Operator)
: 전개연산자도 마찬가지로 복사한 객체 자체는 깊은 복사이지만 내부 객체(2차원 객체)는 얕은 복사가 된다.
const obj = {
a: 1,
b: { c: 2 },
};
const copyObj = {...obj};
copyObj.b.c = 3;
console.log(obj); // { a: 1, b: { c: 3 } }
console.log(obj.b.c === copyObj.b.c); // true
참고