본문 바로가기

Front-end/JavaScript

[Javascript] 참조에 의한 객체 복사

1. 참조에 의한 객체 복사

객체와 원시 티입의 근본적인 차이 중 하나는 '참조의 의해(bt referernce)' 저장되고 복사된다는 것이다. 

(원시값은 '값 그대로' 저장,할당되고 복사된다.)

● 객체의 동작방식

객체를 변수에 할당할 때, 변수에는 객체가그대로 저장되는 것이 아니라, 객체가 저장되어 있는 '메모리 주소'인 객체에 대한 '참조값'이 저장된다. 

let a = {
  'id':1
};

let b = a;

위와같은 코드에서, a에 할당된 객체는 메모리 내 어딘가에 저장되고, 변수a에는 객체를 '참조'할 수 있는 값이 저장된다.

그리고 b에 a를 할당해서 객체가 할당된 변수를 복사할 땐 객체의 참조값이 복사되고 객체는 복사되지 않는다. 변수는 두개 이지만 각 변수엔 동일 객체에 대한 참조 값이 저장되는 것이다.

변수 b에 새로운 property를 추가하면 변경사항을 a에서  또한 확인할 수 있다.

 

2. 참조에 의한 비교

객체를 비교할 때 동등 연산자 (==)와 일치 연산자(===)는 동일하게 동작한다.

let a = {};
let b = a;

console.log(a == b); // true
console,log(a === b); // true

//하지만 형태가 같은 객체라도, 참조에 의해 복사한 객체가 아니라 독립된 객체라면 거짓이 반환된다.
let a = {};
let b = {};

console.log(a == b); //false

 

 

3. 중첩 객체 복사 (깊은 복사. deep cloning)

만약 객체의 프로퍼티가 다른 객체에 대한 참조값일 때는 객체를 어떻게 복사해야 할까?

let user = {
  name:'john',
  sizes: {
    height: 182,
    width: 50
  }
};

//clone.sizes = user.sizes 로 프로퍼티를 복사하는 것만으론 객체를 복사할 수 없다.
//clone.sizes = user.sizes로 프로퍼티를 복사하면 clone과 user는 같은 sizes를 공유하기 때문

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

자바스크립트 라이브라리 lodash의 메서드인 _.cloneDeep(obj)을 사용하면 직접 구현하지 않고도 깊은 복사를 처리할 수 있다.