프로그래밍 언어에는 컴퓨터 메모리에 데이터를 저장하는 두 가지 공간, 스택 과 힙이 존재한다.
스택 은 지역 기본 변수와 객체에 대한 참조를 저장하는 임시 저장 메모리이다.
힙 은 전역 변수를 저장한다.
객체 값은 힙에 저장되고 스택은 해당 값에 대한 참조(포인터)만 포함한다.

객체를 생성하면 스택에 두 개의 포인터(참조)가 생성되고 힙에는 하나의 값만 생성된다.
객체 변수를 만들면 메모리는 값 자체가 아니라 값의 실제 위치에 대한 "주소"를 저장한다.
같은 값을 가리키는 두 개의 참조를 수신하며 이것이 객체 중 하나를 변형하면 항상 두 객체가 모두 변경되는 이유이다.
또한 이것이 복사본이 필요한 이유이다.
얕은 복사를 생성하려면 다음 방법을 사용할 수 있다.
[…] {…}Object.assign()Array.from()Object.create()Array.prototype.concat()const numbers = [1, 2, 3, 4, 5];
const _numbers = [...numbers];
_numbers[0] = 10;
console.log(numbers);
console.log(_numbers);
// [1, 2, 3, 4, 5]
// [10, 2, 3, 4, 5]
const numbers1 = [1, 2, 3, 4];
const numbers2 = [5, 6, 7, 8];
const numbersAll = numbers1.concat(numbers2);
console.log(numbers1); // [1, 2, 3, 4];
console.log(numbersAll); // [1, 2, 3, 4, 5, 6, 7, 8];
const targetObj = {a: 1, b: 2};
const sourceObj = {b: 3, c: 4};
const result = Object.assign(targetObj, sourceObj);
console.log(targetObj); // {a: 1, b: 3, c: 4}
console.log(result); // {a: 1, b: 3, c: 4}
console.log(source0bj); // {b: 3, c: 4}
const set = new Set(['a', 'b', 'c', 'a']);
const array = Array.from(set);
console.log(set); // {'a', 'b', 'c'}
console.log(array); // ['a', 'b', 'c']
const language = {name: "JavaScript", age: 26};
const _language = Object.create(language);
_language.age = 200;
console.log(language);
//{name: "JavaScript", age: 26};
console.log(_language);
//{name: "JavaScript", age: 200};
const language = ["JavaScript", {age: 26, creator: "Brendan Eich"}];
const language = [...language];
_language[1].age = 126;
console.log(language);
console.log(_language);
// ["JavaScript", {age: 126, creator: "Brendan Eich"}]
// ["JavaScript", {age: 126, creator: "Brendan Eich"}]
복사본을 변경하면 소스 값도 변경된다.
이러한 이유는 공유 참조(둘 다 같은 값을 가리킴) 때문이다.
이 문제를 해결하기 위한 Deep copy가 있다.
심층 복사를 생성하려면 다음을 사용할 수 있다.
JSON.parse(JSON.stringify())structuredClone()Lodash 와 같은 타사 라이브러리const language = ["JavaScript", {age: 26, creator: "Brendan Eich"}];
const _language = JSON.parse(JSON.stringify(language));
const __language = structuredClone(language);
_language[1].age = 126;
__language[1].age = 1;
console.log(language);
console.log(_language);
console.log(__language);
// ["JavaScript", {age: 26, creator: "Brendan Eich"}]
// ["JavaScript", {age: 126, creator: "Brendan Eich"}]
// ["JavaScript", {age: 1, creator: "Brendan Eich"}]
이런 방식으로 복사본을 만들면 문제가 해결되고 모든 변형은 직접 변경된 객체에만 적용된다.
이는 복사본이 더 이상 소스 객체와 참조를 공유하지 않기 때문이다. 모두 별도의 값이다.
Deep copy하는 첫 번째 방법은 JSON.stringify() 메서드를 사용하여 JSON 문자열로 변환한 다음 JSON.parse()를 사용하여 객체로 다시 되돌리는 것이다.
이런 식으로 소스 객체와 공유 참조가 없는 완전히 새로운 객체를 받는다. 하지만 이 메서드는 직렬화 가능한 객체에만 사용할 수 있으며, 예를 들어 함수, 심볼, 재귀적 데이터에는 사용할 수 없다.
다른 메서드인 structuredClone() 은 직렬화 가능한 객체를 복제하는 훌륭한 대안이다. 두 번째 선택적 인수를 사용하면 원래 값을 새 객체로 전송할 수 있다. 즉, 전송된 데이터는 소스 객체에서 분리되어 더 이상 액세스할 수 없다.
structuredClone()은 브라우저의 기능이지 JavaScript 자체가 아닙니다.
얕은 복사는 소스 객체와 참조를 공유하며, 중첩되지 않은 객체에 더 적합하며 JavaScript로 프로그래밍할 때 일반적으로 사용된다.
하지만 중첩된 객체를 처리해야 하거나 어떤 값을 받는지 모르는 경우(예: API에서) 대신 깊은 복사를 사용해야 한다.
깊은 복사 는 원본 객체와 참조를 공유하지 않기 때문이다.