기본적으로 자바스크립트의 원시 타입이 아닌 객체 타입은 메모리의 값 자체를 저장하는게 아닌 참조값을 저장한다.
const array = [1,2,3,4];
const sameArray = array;
sameArray.push(5);
console.log(array !== sameArray); // false
위 코드를 확인해보면 sameArray에 array를 할당했지만 결국 sameArray와 array는 같은 참조값을 갖고 있기 때문에 sameArray 값에 새로운 값을 추가해도 마찬가지고 array에도 똑같은 값이 추가 된다.
const array = [1,2,3,4];
const differentArray = [...array];
// 혹은 = array.concat(5)
console.log(array !== differentArray); // true
하지만 spread 연산자를 활용하면 다른 참조값을 가진 differentArray가 만들어져 기존에 array가 다른 배열을 갖게 된다.
하지만 이 방법은 얕은 복사이다
얕은 복사란 객체를 복사할 때 기존 값과 복사된 값이 같은 참조를 가리키고 있는 것을 말한다. 객체 안에 객체가 있을 경우 한 개의 객체라도 기존 변수의 객체를 참조하고 있다면 이를 얕은 복사라고 부른다.
let origin = {
a: 1,
b: {c: 2}
};
let copy = {...origin};
copy.b.c = 3;
console.log(origin === copy) // false
console.log(origin.b.c === copy.b.c); // true
spread 말고도 assign 함수와 slice 함수도 해당한다.
깊은 복사된 객체는 객체 안에 객체가 있을 경우에도 원본과의 참조가 완전히 끊어진 객체를 말합니다.
let origin = {
a: 1,
b: {c: 2}
};
let copy = JSON.parse(JSON.stringify(origin));
copy.b.c = 3;
console.log(origin.b.c === copy.b.c); // false
이 외에도 재귀 함수를 만들어서 하나하나의 값마다 복사해서 새로운 객체를 만드는 방법이 있다.
하지만 위와 같은 방법은 성능에 좋지 않기 때문에 Lodash 같은 라이브러리를 사용하는 편이다.