객체 복사 문제점

김예희·2023년 8월 15일
0

object의 값을 복사할 때는 대상 전체가 아닌 Object 내 주소 값만 복사되는 문제가 발생된다.

예를 들어, user_1을 먼저 선언해놓고 복사해서 user_2에 값을 준다고 해보자.

let user_1 = {
	name: "John",
    age: 27,
};
let user_2 = user_1;
console.log(user_2);

-> console.log(user_2); 는 { name: 'John', age: 27 } 로 맞게 나온다.

하지만 user_2의 값에 변화를 주게되면

user_2.name = "Park"
console.log(user_2);
console.log(user_1);

-> console.log(user_2);와 console.log(user_1); 의 값 모두 동일하게 { name: 'Park', age: 27 } 로 나온다.

🤨 ??

user_2의 값에만 변화를 줬는데 user_1의 값도 동일하게 바꼈다.

이것이 객체 복사 문제점인데 object의 값을 복사할 때는 대상 전체가 아닌 object 내 주소 값만 복사되기 때문이다.
user_1의 주소값을 0x12341234라고 했을 때, user_1을 복사한 user_2는 name과 age값을 복사한게 아니라 주소값인 0x12341234를 복사해오는 것이다.

✔️주소값을 주머니라고 생각하면 user_1과 user_2는 같은 주머니를 갖게 되는 것이므로 user_2의 값에 변화를 줘도 user_1도 같은 값을 갖게 된다.


가리키는 대상 전체를 복사하는 방법은 얕은 복사(Shallow copy)와 깊은 복사(Deep copy)를 통해 가능하다.

얕은 복사 (Shallow copy)

✔️ 복사를 할 때, 새로운 주머니를 만들어서 따로 관리한다고 생각하면 된다.

1. 반복문 for문을 통한 객체 복사

let user_2 = {};
for (let key in user) {
	user_2[key] = user_1[key];
}

2. Object.assign() 함수를 이용한 복사

let user_2 = Object.assign({}, user_1);

-> "빈 객체{ }에 user_1를 merge시켜서 user_2에 넣어줘라."

3. ES6에서부터 지원하는 전개 연산자(Spread Operator)를 이용한 복사

let user_2 = { ...user_1 };

-> ...user_1: "user_1의 모든 값을 전개시켜라"
--> {user_1.name, user_1.age}

❗️❗️❗️이러한 얕은 복사에도 문제점이 있는데, 그것은 객체 내 또 다른 객체가 있다면 복사되지 않는다는 것이다.

예를 들어, 객체 A 안에 이러한 값이 있다고 생각해보자.

객체 A { name: "John",
		age: 23, 
        sizes: { height: 180,
        		 weight: 72, }

여기서 객체 B가 A를 얕은복사를 하게되면 sizes의 값은 주소값으로 받기 때문에 객체 B에서 size: { height: 170 } 로 바꾸면 객체 A에서도 동일하게 변경된다.
--> 객체 내 객체는 얕은 복사를 했을 때 또 다른 주머니를 만드는게 아니라 기존의 주머니를 그대로 사용한다고 보면 된다.


이러한 얕은 복사의 문제점을 해결하기 위해 깊은 복사가 등장하게 됐다.

깊은 복사 (Deep copy)

  1. .재귀 함수를 이용한 깊은 객체 복사
    • for문으로 가능하다. 조금 복잡하다.
  2. .JSON 객체를 이용한 깊은 복사, stringify는 객체를 문자열로 변환하는데 이 때 원본 객체와의 참조가 끊긴다.

0개의 댓글