일반적으로 원시값은 값 그대로 저장 또는 할당됩니다.
let a = 3;
let b = a;
위의 코드에서는 변수 a와 b에 각각의 3이라는 값이 저장 됩니다.
객체는 참조에의해 저장 또는 복사 됩니다. 위와 같이 각각의 값이 변수에 저장되는것이 아니고 객체가 저장되어있는 메모리 주소값(참조값)이 변수에 저장됩니다. 코드를 보면
let a = {
name : "kane";
};
let b = a;
위와 값이 객체가 메모리에 저장되고 그 주소값이 변수에 a에 저장됩니다. 그 후에 변수 b에 변수 a를 복사하면 객체가 복사되는것이 아니라 주소값이 복사 됩니다.
이렇게되면 변수 a,b 는 동일한 객체의 주소값을 공유하게 됩니다.
하나의 객체를 변수 a,b 로 제어할 수 있게 되는 것 입니다.
객체를 비교할때는 동등 연산자 (==), 일치 연산자 (===)를 사용하는데 동일하게 작동 합니다. 비교하는 피연산자인 두 객체가 같은 객체라면 true를 반환 합니다.
let a = {};
let b = a;
console.log(a === b); // true 반환
let a = {};
let b = {};
console.log( a === b); // false 반환
위의 코드와 같이 객체 a를 b에 복사 했다면 a와 b는 같은 객체 입니다. 하지만 a 와 b를 각각의 객체를 생성해 비교한다면 다른 객체라서 false를 반환한것을 확인할 수 있습니다. a와 b는 구조가 같아서 같은 객체처럼 보이지만 다른 주소값을 가지고 있는 독립된 객체 입니다.
위에서 객체를 할당한 변수를 또 다른 변수에 복사하면 객체의 주소값을 복사한다는것을 알게되었습니다. 그럼 똑같이 생긴 객체를 독립된 객체로 복제는 어떻게 할까요?
자바스크립트는 객체 복제 내장 함수를 제공하지 않기 때문에 함수를 이용해 쉽게 복사할수는 없습니다. 하지만 방법은 있습니다.
복사받고 싶은 객체를 생성하고 복사할 객체가 담긴 객체의 프로퍼티를 순회해 원시수준까지 복사하는 방법 입니다. 코드를 보면
let a = {
name : "kane",
};
let b = {};
for (let i in a) {
b[i] = a[i];
}
위와 같이 for in 을 사용해 객체의 프로퍼티를 모두 복사하는 방법이 있다.
또 다른 방법은 Object.assign 함수를 사용하는 것 입니다. 코드를 보면
let a = {
name : "kane",
};
let b = Object.assign({}, a);
위와 같이 코드를 작성하면 b에 a의 프로퍼티가 모두 복제 됩니다. assign 함수의 사용법은 첫번째 인수는 복사 받을 객체가 자리해야하고 그 이후에 인수들은 복사 해줄 객체가 자리하면 됩니다. 복사 해줄 객체의 개수 만큼 인수에 자리하면 됩니다.
기존에 복사 받을 객체에 같은 프로퍼티가 있다면 복사 해줄 객체의 프로퍼티의 값이 복사 받을 객체의 프로퍼티의 값을 덮어버립니다.
프로퍼티 값이 원시값일때는 위의 두가지 방법으로 객체가 복사 됩니다. 하지만 객체의 프로퍼티 값이 참조값일때는 위의 방법으로는 참조값이 복사가 되어 같은 참조값이 가리키는 객체를 공유합니다. 이럴때는 _.cloneDeep(obj)를 사용 깊은 복사를 해야 합니다. assign 을 사용해 복사하는 것은 얕은 복사 라고 합니다.