JS 공부
JS문법종합반 정리 3주차 02 - 객체 복제, 얕은 복사, 깊은 복사
나노다
2024. 11. 6. 19:45
객체 복제의 문제점
객체를 변수에 직접 할당하는 식으로 통째로 복제하면, 복제된 객체의 프로퍼티를 변경할지라도 불변성 땜시 기존 객체와 복사 객체가 같다고 판단됨.
/* 기존 객체 */
var user = {
name: 'wonjang',
gender: 'male',
};
/* 객체를 복사하고, name 프로퍼티의 값을 바꾸는 함수 */
var changeName = function (user, newName) {
var newUser = user;
newUser.name = newName;
return newUser;
};
/* 복사 객체 생성 */
var user2 = changeName(user, 'twojang');
/* name의 값이 다름에도 불구하고 두 객체가 같다고 판단 */
console.log(user === user2); // 반환 : true
얕은 복사
기존 객체와 내용물은 같은 아예 새 배열을 생성하는 식으로 복제를하면 복사 객체와 다르다고 판단함. 하지만 중첩 객체인 경우 하위 객체의 복제는 역시 기존 것과 같다고 판단...
/* 기존 객체 (중첩 객체) */
var user = {
name: 'wonjang',
urls: {
portfolio: 'http://github.com/abc',
blog: 'http://blog.com',
facebook: 'http://facebook.com/abc',
}
};
/* 얕은 복사 함수 */
var copyObject = function (target) {
// 새 객체를 만듦
var result = {};
// 새 객체에 기존 객체의 프로퍼티를 옮겨 닮음
for (var prop in target) {
result[prop] = target[prop];
}
return result;
}
/* 복제 객체 생성 */
var user2 = copyObject(user);
/* 상위 프로퍼티 변경 시 다르다 판단 */
user2.name = 'twojang';
console.log(user.name === user2.name); // false
/* 하위 프로퍼티 변경했음에도 불구하고 같다 판단 */
user.urls.portfolio = 'http://portfolio.com';
console.log(user.urls.portfolio === user2.urls.portfolio); // true
깊은 복사
재귀적 수행을 통해 중첩 객체의 프로퍼티 중 기본형 데이터는 그냥 복제, 참조형 데이터는 다시 그 내부의 프로퍼티를 복제하는 방법을 통해 온전히 다른 복제 객체를 만들 수 있음
- 재귀적 수행 : 함수나 알고리즘이 자기 자신을 호출해 반복 실행하는 것
/* 기존 객체 (중첩에 중첩 객체임) */
var obj = {
a: 1,
b: { c: null, d : [1, 2], }
};
/* 깊은 복사 함수 */
var copyObjectDeep = function(target) {
var result = {};
if (typeof target === 'object' && target !== null) {
for (var prop in target) {
result[prop] = copyObjectDeep(target[prop]);
}
} else {
result = target;
}
return result;
}
/* 복제 객체 생성 */
var obj2 = copyObjectDeep(obj);
/* 복제 객체의 프로퍼티 변경 */
obj2.a = 3;
obj2.b.c = 4;
obj2.b.d[1] = 3;
/* 중첩객체 속 모든 요소가 달라졌음 */
console.log(obj === obj2); // 반환 : false
console.log(obj.b.c === obj2.b.c); // 반환 : false
console.log(obj.b.d[1] === obj2.b.d[1]); // 반환 : false