그렇다. 자바스크립트에서 선언한 변수나 함수, 객체 등을 복사할 수 있는데 이 복사가 깊은 복사와 얕은 복사로 나뉜다.
기본적으로 얕은 복사와 깊은 복사는 다음과 같다.
이를 알기 위해선 먼저, 원시형과 참조형에 대해 알아야 한다.
MDN에 따르면, 자바스크립트에서 원시값이란 객체가 아니면서 메서드도 가지지 않는 데이터이다. 원시값에는 string, number, bigint, boolean, undefined, symbol, null이 존재한다.
그리고 이러한 원시값의 특징은 불변하고 변형할 수 없다. 하지만 재할당은 가능하다.
즉, 불변할 수 없으나 재할당은 가능한 원시값의 특징에 따라 원시값을 복사하면 새 메모리 공간이 확보된다. 깊은 복사가 일어난다.
따라서 무작정 복사를 하는 것이 아니라, 원시형과 참조형 값의 특징에 따라 깊은 복사와 얕은 복사에 대한 이해를 토대로 코드를 작성해야 한다.
만약 내가 원하는 것이 원본에는 영향을 주지 않으면서 값을 바꾸고 싶은데 그것이 얕은 복사였다면 나중에 문제가 생길 수 있다.
보통 복사를 많이 하는 것이 객체일 것이다. 이는 다양한 방법이 있지만 대표적으로 spread 연산자를 통해서 가능하다.
const me = {
name : "kim",
age : 80,
skills : { first : "javascript", second : "react" }
}
spread 연산자를 통해 복사를 하고 객체 안의 age를 바꾼다고 하면
const clone = {...me}
clone.age = 200;
객체는 참조형이기 때문에 원본의 age도 200으로 바뀌었을 것이라고 예상할 수 있지만, spread연산자를 이용해서 복사했기 때문에 원본에는 영향을 주지 않고 clone 변수에서만 age가 바뀌게 된다.
하지만 이는 depth 1 까지만 적용이 가능하다!
me 객체 안의 skills 는 다시 객체인데, 이러한 객체 안의 또 다른 객체를 depth 2라고 한다.
clone의 skills를 바꾸면 다시 원본에도 영향을 끼친다.
Obeject.assign도 참조형인 객체의 깊은 복사를 구현할 수 있지만 이도 spread연산자와 같게 depth 1까지만 가능하다.
만약 그 이상의 depth에서도 깊은 복사를 원한다면, lodash라는 라이브러리를 사용해야 한다!