이전에 하나의 데이터만 담을 수 있는 애들은 원시값이라고 했다.
객체와 원시타입의 차이중 하나는 객체는 참조에 의해
저장, 복사가 되는 것이다.
객체와는 다르게 원시값은 값 그대로
저장되고 할당이 된다.
=> 원시값:
let message = "Hello"; let phrase = message'
이렇게 각각 독립된 변수에 문자열 Hello를 저장한다.
반면에 객체는..
=> 객체:
객체의 변수에는 값이 그대로 저장되는 것이 아니고, 객체가 저장되어있는 주소
라는 참조값이 저장이 된다.
객체는 메모리 어딘가 저장이되고 변수에는 객체를 참조할 수 있는 값이 저장이된다.
따라서 객체가 할당된 변수를 복사할때는 이 참조값만 복사가 되고 객체는 복사가 되지 않는다.
let user {
name:"John"
}
let admin = user;
```
변수는 두개이지만 각 변수에는 같은 객체에 대한 주소(참조값)만 저장된다.
#### 참조에 의한 비교
객체 비교시 동등연산자 `==`와 일치 연산자 `===` 는 동일하게 작동한다.
비교시 피연산자인 두 객체가 동일한 경우에 true를 반환하는것이다.
```js
let a ={};
let b = a;
a == b => true
a === b => true
a와 b는 둘다 같은 객체를 참조(같은 주소를 가지기때문에)하기에 둘의 비교는 true가 된다.
반면
let a = {};
let b = {};
a == b =>false;
여기서 a와 b는 둘다 형태가 같아 true를 반환 할 것 같지만 그렇지 않다.
할당 연산자가 들어가고 객체를 만들게 되면 그건 곳, 다른 주소를 가지는 객체가 생성이 된다는 의미이므로 독립된 다른 객체이다.
객체가 할당된 변수를 복사하려면 동일한 객체에 대한 주소(참조값)이 하나 더 만들어지는 것이다.
그럼 객체를 복사하고 싶다면?? => 기존 객체와 값은 같으면서 다른 주소를 가지게 하고 싶을 경우..
기존객체를 순회해 원본의 프로퍼티들을 복사하면 된다.
let user = {
name: "John",
age: 30
};
let clone = {}; // 새로운 빈 객체
// 빈 객체에 user 프로퍼티 전부를 복사해 넣습니다.
for (let key in user) {
clone[key] = user[key];
}
Object.assign이라는것을 사용하는 예시도 있다.
이 메서드는 두 객체를 합치는 메서드 이다.
첫번째 인자로는 목표로 하는 객체 즉, 어느 객체에 반영할 것인지를 , 두번째 인자에는 복사하고자 하는 객체를 넣을 수 있다.
목표로 하는 객체에 같은 프로퍼티가 있다면 덮어쓰기가 된다.
let user = {
name: "John",
age: 30
};
let clone = Object.assign({}, user);
user에 있는 모든 프로퍼티가 빈 객체에 복사되고 변수에 할당된다.
이 방법이 아니어도 직접 원본에서 각 프로퍼티를 뽑아 복사하는 방법이 있다.
그런데 객체 안에 프로퍼티에 객체가 있을 수도 있다.
이때는 이것 또한 객체이기에 참조 주소만 복사된다. 따라서 이 문제를 해결하기 위해서는 이 객체의 구조도 복사해주는 반복문을 사용해야하는데, 이것을 깊은 복사라고 한다.
깊은 복사시 사용하는 알고리즘도 존재하지만 자바스크립트 라이브러리인 lodash에서 제공하는_cloneDeep(obj)라는 메서드를 사용하면 쉽게 처리할 수 있다.