자바스크립트_기초_4.2

HwiJeongLee·2021년 9월 8일
0

자바스크립트

목록 보기
25/28

참조에 의한 객체 복사

객체형과 원시형의 근본적인 차이는 참조에 의한 복사 vs 값에 의한 복사입니다.

🎈 원시형은 '값 그대로' 저장, 할당되고 복사되고 객체형은 '참조에 의해' 저장, 복사됩니다.

let message = "Hi!"
let phrase = message;

두 개의 변수에는 각각 "Hi!"가 저장됩니다.

🎈 변수에는 객체가 그대로 저장되는 것이 아닌 객체가 저장되어있는 '메모리 주소'인 객체에 대한 '참조 값'이 저장됩니다.

이번에는 변수에 객체를 할당해봅시다.

let user = {
  name: "John"
};

let admin = user;
admin.name = "Pete"
alert(user.name) // Pete가 출력됩니다.

객체는 메모리 어딘가에 저장되고 변수 user에는 객체를 참조할 수 있는 값(주소값)이 저장됩니다.

즉, 객체가 할당된 변수를 복사할 때는 객체의 참조 값이 복사되고 객체는 복사되지 않습니다.

admin = user를 하면 user가 갖고 있는 객체의 주소를 admin도 할당받게 됩니다.
즉 admin에서 name값을 수정하면 user도 name 값이 수정됩니다.

참조에 의한 비교

객체 비교 시 동등 연산자 ==와 일치 연산자 ===는 동일하게 동작합니다.
피연산자인 두 객체가 동일한 객체인 경우 참을 반환합니다.

let a = {}
let b = a;

alert(a==b) // true
alert(a===b) // true

위의 경우 두 변수가 같은 객체를 참조하므로 결과는 true가 반환됩니다.

let a = {}
let b = {};

alert(a==b) // false
alert(a===b) // false

위의 경우 객체가 모두 비어있는 점은 동일하지만 같은 객체가 아닙니다. 즉 객체가 저장되어 있는 주소값이 다르기때문에 일치, 동등을 비교하면 false가 반환됩니다.

객체 복사, 병합 과 Object.assign

객첵가 할당된 변수를 복사하면 동일한 객체에 대한 참조 값이 하나 더 만들어집니다.

만약 기존에 있는 객체와 똑같으면서 독립적인 객체를 만들고 싶다면 어떻게 해야 할까요?

새로운 객체를 만들고 기존 객체의 프로퍼티들을 순회해 원시 수준까지 프로퍼티를 복사하면 됩니다.

하지만 자바스크립트는 객체 복제 내장 메서드를 지원하지 않기 때문에 선호되지는 않습니다. 사실 객체를 복제할 일도 거의 없습니다. 참조에 의한 복사로 대부분 일이 해결 가능합니다.

Object.assign 방식을 사용할 수도 있습니다.

Object.assign(dest,src1, ssrc2,...)

첫 번째 인수 dest는 목표로 하는 객체입니다.
이어지는 인수들은 복사하고자 하는 객체입니다.

dest를 제외한 인수의 프로퍼티는 모두 첫 번째 인수인 객체로 복사됩니다.

let user = { name: "John" };

let permissions1 = { canView: true };
let permissions2 = { canEdit: true };

// permissions1과 permissions2의 프로퍼티를 user로 복사합니다.
Object.assign(user, permissions1, permissions2);

// now user = { name: "John", canView: true, canEdit: true }

만약 목표 객체에 동일한 이름을 가진 프로퍼티가 있다면 기존 값이 덮어씌워 집니다.

중첩 객체 복사

앞의 예시는 user의 모든 프로퍼티가 원시값인 경우만을 고려했습니다.
만약 프로퍼티는 다른 객체에 대한 참조값이라면 어떻게 해야 할까요?

let user = {
  name: "John",
  sizes: {
    height: 182,
    width: 50
  }
};
alert( user.sizes.height ); // 182

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)입니다.

profile
초보 개발자의 개발 공간

0개의 댓글