객체 #2

kevin kim·2020년 6월 14일
0

참조에 의한 객체 복사

객체와 원시 타입의 근본적인 차이 중 첫 번째는, 객체는 참조에 의해 저장되고 복사된다는 것이다.
원시값(문자열, 숫자, 불린 값)은 값 그대로 저장,할당되고 복사되는 반면에 말이다.
그런데 객체의 동작방식은 이와 다르다.
변수에는 객체가 그대로 저장되는 것이 아니라, 객체가 저장되어 있는 '메모리 주소'인 객체에 대한 '참조 값'이 저장된다.
예시 1)

let user = {
  name: "kevin"
};

예시 2)

let a = {};
let b = a; // 참조에 의한 복사

alert( a == b ); // true, 두 변수는 같은 객체를 참조한다.
alert( a === b ); // true

중첩 객체 복사

let user = {
  name: "John",
  sizes: {
    height: 182,
    width: 50
  }
};

alert( user.sizes.height ); // 182

clone.sizes = user.sizes로 프로퍼티를 복사하는 것만으론 객체를 복제할 수 없습니다. user.sizes는 객체이기 때문에 참조 값이 복사되기 때문입니다. clone.sizes = user.sizes로 프로퍼티를 복사하면 cloneuser는 같은 sizes를 공유하게 됩니다. 코드는 아래와 같다.

let user = {
  name: "John",
  sizes: {
    height: 182,
    width: 50
  }
};

let clone = Object.assign({}, user);

alert( user.sizes === clone.sizes ); // true, 같은 객체

// user와 clone은 sizes를 공유한다.
user.sizes.width++; // 한 객체에서 프로퍼티를 변경
alert(clone.sizes.width); // 51, 다른 객체에서 변경 사항을 확인

이 문제를 해결하려면 user[key]의 각 값을 검사하면서, 그 값이 객체인 경우 객체의 구조도 복사해주는 반복문을 사용해야 한다. 이런 방식을 깊은 복사(deep cloning)라고 한다.

요약

객체는 참조에 의해 할당되고 복사된다. 변수에는 '객체' 자체가 아닌 메모리상의 주소인 '참조'가 저장된다. 따라서 객체가 할당된 변수를 복사하거나 함수의 인자로 넘길 땐 객체가 아닌 객체의 참조가 복사된다.
그리고 복사된 참조를 이용한 모든 작업(프로퍼티 추가,삭제 등)은 동일한 객체를 대상으로 이뤄진다.

객체의 진짜 복사본을 만드려면 얕은 복사(shallow copy)를 가능하게 해주는 Object.assign이나 깊은 복사를 가능하게 해주는 _.cloneDeep(obj)를 사용하면 된다. 얕은 복사본은 중첩 객체를 처리하지 못한다는 점을 기억하자!!

profile
프론트엔드 개발자

0개의 댓글