얕은 복사 (Shallow copy) 깊은 복사(Deep copy)
참조타입의 복사 방법은 얕은 복사(shallow copy)와 깊은 복사(deep copy)로 나뉜다.
얕은 복사는 참조 타입 데이터가 저장한 '메모리 주고 값'을 복사한 것을 의미한다.
반대로 깊은 복사(deep copy)는 새로운 메모리 공간을 확보해 완전히 복사하는 것을 의미한다.
1. 얕은 복사(Shallow copy)
얕은 복사(Shallow copy)는 참조값의 복사를 나타낸다.
const user = {
name : 'luka'
};
const copyUser = user;
copyUser.name = 'lukas';
console.log(user.name); // lukas
console.log(user === copyUser); // true
user라는 객체를 copyUser에 복사한 후 copyUser.name을 변경하면 기존의 user.name 값 역시 변경된다.
아래 두 객체를 비교해 보아도 true가 나오는 것을 확인할 수 있다.
⏺ Object.assign()
Object.assign()을 이용하면 객체 자체는 깊은 복사가 이루어지지만, 2차원 이상의 객체는 얕은 복사가 실행된다.
아래 예시에서 참고하자.
const user = {
name: {firstName: 'luka'},
age: 10
};
const copyUser = Object.assign({}, user);
copyUser.name.firstName = 'lukas';
copyUser.age = 11;
console.log(user === copyUser) //false
console.log(user.name.firstName) //lukas
console.log(user.age) //10
⏺ 전개 연산자(Spread Operator)
전개 구문 역시 Object.assign()과 마찬가지로 2차원 이상의 객체는 얕은 복사가 실행된다.
const user = {
name: {firstName: 'luka'},
age: 10
};
const copyUser = {...user};
copyUser.name.firstName = 'lukas';
copyUser.age = 11;
console.log(user === copyUser) //false
console.log(user.name.firstName) //lukas
console.log(user.age) //10
2. 깊은 복사(Deep Copy)
깊은 복사(Deep Copy)는 복사된 객체가 다른 주소를 참조한다. 즉 새로운 메모리 공간에 값을 복사한다.
⏺ 재귀 함수
재귀 함수를 만들어 값을 복사하는 방법이다.
let user = {
age: 10,
name: {firstName: 'luka'}
};
function isCopyUser(user) {
let res = {};
for(let key in user) {
if(typeof user[key] === 'object') {
res[key] = isCopyUser(user[key]);
} else {
res[key] = user[key];
}
}
return res;
}
let copy = isCopyUser(user);
copy.name.firstName = 'lukas';
console.log(user.name.firstName); //luka
⏺ JSON 객체의 메서드 이용
JSON.stringify 와 JSON.parse를 이용한 깊은 복사(Deep Copy)를 실현하는 방법이다.
const user = {
name: {firstName: 'luka'},
age: 10
};
const copyUser = JSON.parse(JSON.stringify(user));
copyUser.name.firstName = 'lukas';
console.log(user.name.firstName) //luka
하지만 위 방법은 단점이 존재한다.
1. 다른 방법들에 비해 성능이 느리다
2. JSON.stringify() 메서드는 함수를 만났을 때 undefined로 처리된다.
⏺ lodash 라이브러리 cloneDeep()
lodash 라이브러리의 cloneDeep() 메서드를 이용하여 별다른 커스텀 재귀함수를 사용하지 않고 편리하게 깊은 복사(Deep Copy)가 가능하다. 해당 라이브러리를 설치해야 사용할 수 있다. 사용 방법은 따로 기재하지 않겠다.
'Front-end School > JS' 카테고리의 다른 글
[Javascript] environmentRecord와 호이스팅(Hoisting) (2) | 2023.01.17 |
---|---|
[Javascript] 실행 컨텍스트(Execution Context) (0) | 2023.01.17 |
[Javascript]원시형과 참조형 (0) | 2023.01.12 |
[Javascript] 이벤트 버블링(bubbling)이란? 버블링 중단하기 (0) | 2022.02.28 |
[Javascript] 요소 찾기 querySelector, querySelectorAll (0) | 2022.02.26 |