[JavaScript] 객체 복사

2020. 8. 12. 22:20Programming Languages/JavaScript

객체와 원시 타입의 근본적인 차이 중 하나는 객체는 참조에 의한 복사에 의해 저장되고 복사된다는 것입니다. 원시값(문자열, 숫자, 불린 값)은 값 자체가 저장되고 복사됩니다.

 

const message = "Hello";
const text = message;

 

위 코드를 실행하면 아래와 같이 두 개의 독립된 변수에 각각 문자열 "Hello"가 저장됩니다. 

 

 

그런데 객체의 동작방식은 이와 다릅니다.

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

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

 

let user = { name: "John" };

let admin = user;

admin.name = "Anna"; // user와 같은 메모리 주소를 공유하기 때문에 name이 변경됨

console.log(user.name); // "Anna"가 출력됨. 

 

 

 

 

객체를 비교할 때 ==와 ===는 동일하게 동작합니다. 비교 시 피연산자인 두 객체가 동일한 객체인 경우에, 즉 같은 참조값을 가지고 있다면 참을 반환합니다.

 

let a = {name: "John"};
let b = a;

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

 

하지만 프로퍼티가 동일하다고 같은 참조값을 가지는 것은 아닙니다. 아래의 예시를 보면 같은 프로퍼티를 가졌지만 false가 출력되는 것을 볼 수 있습니다. 왜냐하면 위 예시는 b에 참조에 의한 복사를 통해 a의 참조값을 복사한 것이고 아래 예시는 각각의 독립된 참조값을 가지는 객체 a와 b를 선언한 것이기 때문입니다.

 

let a = {name: "John"};
let b = {name: "John"};

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

 

그렇다면 객체를 복사하여 기존의 객체와 똑같은 객체를 만드려면 어떻게 해야 될까요?

먼저 for문을 활용하는 방법이 있습니다. 아래 코드를 봅시다.

 

let user = {
  name: "John",
  age: 30,
};

let clone = {};

// clone 객체에 user의 프로퍼티를 모두 복사합니다.
for (let key in user) {
  clone[key] = user[key];
}

console.log(clone.name); // "John"

 

두 번째로 Object.assign을 사용하는 방법이 있습니다.

 

위 사진은 assign 메소드의 사용 방법을 설명해놓은 것입니다. 한 번 정독하시면 좋을 것 같습니다.

사용 방법을 간단히 알아봅시다.

target: object - 복사한 프로퍼티들을 담을 객체입니다.

... sources: any[] - 복사하고자하는 객체입니다. 필요에 따라 얼마든지 객체를 인수로 사용할 수 있다는 것을 나타냅니다. 

sources 를 복사하고 target에 담은 뒤 target을 반환합니다. 예시를 한 번 봅시다.

 

let user = {
  name: "John",
  age: 30
};

let city = { city: "Seoul" };
let hasGirlFriend = { hasGirlFriend: false };

// city와 hasGirlFriend의 프로퍼티를 복사합니다.
Object.assign(user, city, hasGirlFriend);

/* user = {
  name: "John",
  age: 30,
  city: "Seoul",
  hasGirlFriend: false,
}
*/

 

만약 동일한 프로퍼티 키가 있는 경우엔 기존 값이 새로운 값으로 덮어쓰기됩니다.

 

let user = {
  name: "John",
}

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

 

위와 같이 빈 객체에 user 프로퍼티를 복사하여 clone이라는 객체를 만들 수도 있습니다.

 

만약 복사하는 객체의 프로퍼티 중 값이 객체인 경우에는 어떻게 될까요?

이런 경우에는 프로퍼티 값의 참조값이 복사됩니다. 즉, 값이 복사되지 않고 참조값이 복사되어 복사한 객체에서 값을 수정할 경우 기존의 객체값이 변경됩니다. 이 문제를 해결하려면 프로퍼티 값을 검사하면서, 그 값이 객체라면 객체의 구조도 복사해주는 반복문을 사용해야 합니다. 이런 방식을 '깊은 복사(deep cloning)'이라고 합니다. 이 경우는 저도 아직 접헤보지 않아서 이 정도로만 설명하겠습니다. 이런 것도 있다고 생각합시다.

'Programming Languages > JavaScript' 카테고리의 다른 글

[JavaScript] Promise  (0) 2021.05.12
[JavaScript] 가비지 컬렉션  (0) 2020.08.17
[JavaScript] 객체  (0) 2020.08.11
[JavaScript] Prototype  (0) 2020.08.02
[JavaScript] 함수(Function)  (0) 2020.08.02