자바스크립트에서 얕은 복사와 깊은 복사란?

kwakjihoon·2025년 1월 16일
post-thumbnail

자바스크립트에서 값은 원시값참조값 두 가지 데이터 타입의 값이 존재한다.

  • 원시값: Number, String, Boolean, Null, Undefined 등 기본 자료형을 의미한다.
    • 변수의 메모리 공간에 실제 데이터 값이 저장된다.
    • 변수를 조작하면 저장된 실제 값이 조작된다.
  • 참조값: Object, Symbol 등 여러 자료형으로 구성되는 메모리에 저장된 객체를 의미한다.
    • 변수에 객체를 저장하면 독립적인 메모리 공간에 값을 저장하고, 메모리 공간의 참조(위치 값)를 저장하게 된다.
    • 할당된 변수를 조작하면 객체 자체를 조작하는 것이 아닌, 해당 객체의 참조(위치 값)를 조작하는 것이다.

얕은 복사(Shallow Copy)

객체의 참조값(주소 값)을 복사한다. 복사된 변수는 객체가 저장된 메모리 공간의 참조를 가리키기 때문에 객체를 수정하면 기존 객체를 저장한 변수에도 영향을 끼친다.

const a = {  
	one: 1,  
	two: 2,
};

let b = a; 

b.one = 3; 

console.log(a); // { one: 3, two: 2 } 출력
console.log(b); // { one: 3, two: 2 } 출력 

// 기존 값에 영향을 끼친다.
const original = {
  name: 'Alice',
  info: {
    age: 25,
    city: 'New York'
  }
};

const shallowCopy = { ...original }; // 얕은 복사, 최상위 속성 name(문자열)과 info(객체 타입)
shallowCopy.name = 'Bob'; // 원시값(문자열) 변경 (원본 영향 없음)
shallowCopy.info.age = 30; // 중첩 객체 수정 (원본 영향 있음)

console.log(original.info.age); // 30 (참조 공유)

깊은 복사(Deep Copy)

객체의 실제 값을 복사한다. 메모리 공간이 독립적이기 때문에, 복사를 하고 값을 수정해도 기존 원시값을 저장한 변수에 영향을 끼치지 않는다.

const a = 'a';
let b = 'b'; 

b = 'c'; 

console.log(a); // 'a';
console.log(b); // 'c'; 

// 기존 값에 영향을 끼치지 않는다.
const original = {
  name: 'Alice',
  info: {
    age: 25,
    city: 'New York'
  }
};

// JSON 방식 (단, 함수나 undefined는 제외됨)
const deepCopy = JSON.parse(JSON.stringify(original));
//JSON.stringify(): 객체를 json 문자열로 변환하는데, 이 과정에서 원본 객체와의 참조가 끊어짐.
//JSON.parse(): 문자열로 변환된 json을 다시 자바스크립트 객체로 파싱해줌.
deepCopy.info.age = 30;

console.log(original.info.age); // 25 (원본 영향 없음)

JSON 방식이 간단하지만, 다른 방법에 비해 느리고 객체가 함수 타입(function)일 경우, undefined로 처리한다.

다른 방법으론 Lodash 라이브러리를 사용하거나 수동으로 복잡한 경우를 재귀 함수로 해결하는 방법이 있다.

ref: https://bbangson.tistory.com/78

profile
딥다이브 습관화 하기 ☺️

0개의 댓글