얕은 복사는 문제가 있다. 무엇일까?
중첩된 객체를 얕은 복사를 할 때가 문제이다. 중첩된 객체란 객체 안에 객체가 있는 경우다. 이 중첩된 객체가 복사당하면 복사 결과물인 객체와는 당연히 따로 서로 다른 객체가 되어야 할 것이다. 그런데 그게 안된다. 복사당한 객체를 수정하면 복사결과 객체까지 바뀌어 버린다.
반대로 복사결과 객체를 수정하면 복사당한 객체도 바뀐다. 객체내부의 중첩객체를 수정하면 그렇다.
얕은 복사는 for in 구문을 활용해서 하는데 코드는 아래와 같다. 문제가 있는 코드다.
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 ~ in 구문을 이용하여, 객체의 모든 프로퍼티에 접근할 수 있습니다.
// 하드코딩을 하지 않아도 괜찮아요.
// 이 copyObject로 복사를 한 다음, 복사를 완료한 객체의 프로퍼티를 변경하면
// 되겠죠!?
for (var prop in target) {
result[prop] = target[prop];
}
return result;
}
var user2 = copyObject(user);
user2.urls.portfolio = 'http://portfolio.com';
console.log(user)
console.log(user2)
console.log(user.urls.portfolio, user2.urls.portfolio);
무슨 문제가 있을까?
user2.urls.portfolio = 'http://portfolio.com';
이 코드로 user2객체의 url 의 portfolio 프로퍼티만 바꾸고 싶었는데 user 객체의 해당내용까지 바뀌어 버린다. 콘솔을 확인해 보면 나온다.
이 원인은 메모리에서 user와 user2 안에 있는 urls 객체가 모두 같은 주소를 바라보고 있기 때문이다. user2의 내용을 수정했는데 그 하나의 주소의 내용이 바뀌어 버리니 user 의 내용까지 똑같이 바뀌는 것이다.
아래 예제를 보면 이해가 쉽다.
[예제]
obj2의 c 만 수정했는데 c의 주소인 7103이 수정 후부터는 5004를 바라보게 되었고 이는 obj1 에까지 영향을 미치게 되었다.
이걸 해결하려면 어떻게 해야할까? 깊은 복사를 해야 한다. 깊은 복사는 재귀함수로 한다. 이건 다음 포스팅에서 ^^
'자바스크립트 리뷰' 카테고리의 다른 글
getter와 setter 간단명료 정리! (0) | 2023.04.30 |
---|---|
깊은 복사는 다른 객체를 생성해 낸다고 보아도 되겠다. [JS 문법 종합반 3주차 - 1] (0) | 2023.04.12 |
중첩 데이터의 메모리 저장방식 [JS문법 종합반 3주차 ] (0) | 2023.04.11 |
메모리: 참조형 데이터는 가변하다. [ JS문법 종합반 3주차 -1] (0) | 2023.04.11 |
메모리: 변수와 상수 그리고 불변하다와 불변하지 않다. [ JS문법 종합반 3주차] (0) | 2023.04.11 |