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)를 통해 가능하다.
✔️ 복사를 할 때, 새로운 주머니를 만들어서 따로 관리한다고 생각하면 된다.
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에서도 동일하게 변경된다.
--> 객체 내 객체는 얕은 복사를 했을 때 또 다른 주머니를 만드는게 아니라 기존의 주머니를 그대로 사용한다고 보면 된다.
이러한 얕은 복사의 문제점을 해결하기 위해 깊은 복사가 등장하게 됐다.