SW/JavaScript

JavaScript의 얕은 복사와 깊은 복사: 차이점과 활용 방법

얇은생각 2024. 8. 6. 07:30
반응형

JavaScript에서 객체를 복사할 때 사용하는 두 가지 주요 방법인 얕은 복사(Shallow Copy)와 깊은 복사(Deep Copy)에 대해 자세히 알아보겠습니다. 객체 복사는 코드 작성 시 자주 사용되는 기능으로, 이를 제대로 이해하는 것은 객체 조작과 메모리 관리를 효율적으로 수행하는 데 중요합니다. 이번 글에서는 얕은 복사와 깊은 복사의 차이점을 설명하고, 각각의 장단점 및 사용 사례를 통해 언제 어떤 복사 방법을 사용하는 것이 적절한지 알아보겠습니다.

 

JavaScript의 얕은 복사와 깊은 복사: 차이점과 활용 방법

 

얕은 복사(Shallow Copy)?

얕은 복사는 새로운 객체를 생성하지만, 원본 객체와 동일한 메모리 참조를 공유하는 속성을 포함합니다. , 얕은 복사본의 속성을 변경하면 원본 객체의 속성도 변경됩니다. 이는 객체의 최상위 수준에서만 복사되기 때문입니다.

 

JavaScript에서 얕은 복사를 만드는 방법

1. Object.assign()

Object.assign() 메소드는 원본 객체의 모든 열거 가능한 속성을 복사하여 새 객체를 생성합니다. 다음은 그 예입니다:

let originalObj = { name: "John", age: 30 };
let copiedObj = Object.assign({}, originalObj);

copiedObj.age = 40;

console.log(originalObj.age); // 출력: 40

 

위 예제에서 copiedObjage 속성을 변경하면 originalObjage 속성도 변경됩니다.

 

 

2. 전개 연산자(Spread Operator)

전개 연산자 ...를 사용하여 객체의 속성을 새 객체로 펼쳐 얕은 복사를 만들 수 있습니다. 다음은 그 예입니다:

let originalObj = { name: "John", age: 30 };
let copiedObj = { ...originalObj };

copiedObj.age = 40;

console.log(originalObj.age); // 출력: 40

 

마찬가지로, copiedObjage 속성을 변경하면 originalObjage 속성도 변경됩니다.

 

 

깊은 복사(Deep Copy)?

깊은 복사는 원본 객체의 모든 속성과 하위 속성을 포함하는 새로운 객체를 생성합니다. 따라서 깊은 복사본에 대한 변경은 원본 객체에 영향을 미치지 않습니다.

 

JavaScript에서 깊은 복사를 만드는 방법

1. JSON.parse()JSON.stringify()

깊은 복사를 가장 쉽게 만드는 방법은 JSON.parse()JSON.stringify()를 사용하는 것입니다. 다음은 그 예입니다:

let originalObj = { name: "John", age: 30, address: { city: "New York", state: "NY" } };
let copiedObj = JSON.parse(JSON.stringify(originalObj));

copiedObj.address.city = "Los Angeles";

console.log(originalObj.address.city); // 출력: New York

 

이 예제에서 copiedObjcity 속성을 변경해도 originalObjcity 속성에는 영향을 미치지 않습니다.

 

2. 재귀(Recursion)

재귀를 사용하여 원본 객체의 모든 속성과 하위 객체를 복사하여 깊은 복사를 만들 수 있습니다. 다음은 그 예입니다:

function deepCopy(obj) {
  let copiedObj = Array.isArray(obj) ? [] : {};

  for (let key in obj) {
    if (typeof obj[key] === "object" && obj[key] !== null) {
      copiedObj[key] = deepCopy(obj[key]);
    } else {
      copiedObj[key] = obj[key];
    }
  }

  return copiedObj;
}

let originalObj = { name: "John", age: 30, address: { city: "New York", state: "NY" } };
let copiedObj = deepCopy(originalObj);

copiedObj.address.city = "Los Angeles";

console.log(originalObj.address.city); // 출력: New York

 

이 예제에서는 deepCopy() 함수가 원본 객체의 모든 속성과 하위 속성을 재귀적으로 복사합니다. 따라서 복사본에 대한 변경은 원본 객체에 영향을 미치지 않습니다.

 

 

얕은 복사와 깊은 복사의 장단점 및 사용 사례

얕은 복사

 

장점:

  • 빠른 복사: 복사 속도가 빠르고 메모리 사용량이 적습니다.
  • 참조 공유: 참조를 공유하여 동일한 객체를 여러 곳에서 사용할 수 있습니다.

 

단점:

  • 데이터 변경 위험: 복사본과 원본 객체가 동일한 참조를 가지므로, 하나를 변경하면 다른 것도 변경됩니다.
  • 중첩 객체 처리 부족: 중첩된 객체까지 복사하지 않기 때문에, 중첩 객체의 속성 변경 시 문제가 발생할 수 있습니다.

 

사용 사례:

  • 불변 객체: 데이터 변경이 거의 없는 불변 객체에 적합합니다.
  • 간단한 데이터 구조: 간단한 데이터 구조에서는 얕은 복사가 충분히 유용합니다.

 

깊은 복사

장점:

  • 독립된 복사본: 복사본이 원본 객체와 완전히 독립적이므로, 복사본의 변경이 원본에 영향을 미치지 않습니다.
  • 중첩 객체 복사: 모든 하위 객체까지 완전히 복사합니다.

 

단점:

  • 느린 복사 속도: 복사 과정이 복잡해지고 메모리 사용량이 증가할 수 있습니다.
  • 성능 저하: 큰 객체나 깊이 중첩된 객체를 복사할 때 성능이 저하될 수 있습니다.

 

사용 사례:

  • 독립적인 객체 생성: 원본 객체와 독립적인 복사본이 필요한 경우에 적합합니다.
  • 복잡한 데이터 구조: 중첩된 객체가 많은 복잡한 데이터 구조에 적합합니다.

 

 

결론

JavaScript에서 얕은 복사와 깊은 복사의 차이를 이해하는 것은 올바른 객체 조작과 메모리 관리에 중요합니다. 얕은 복사는 메모리 참조를 공유하는 새로운 객체를 생성하여, 복사본과 원본 객체 간에 변경 사항이 서로 영향을 미칩니다. 반면, 깊은 복사는 원본 객체와 완전히 독립적인 새로운 객체를 생성하여, 복사본과 원본 객체 간의 상호 영향이 없습니다.

코드의 요구사항과 원하는 결과에 따라 얕은 복사와 깊은 복사 중 어떤 방법을 사용할지 결정해야 합니다. 얕은 복사는 참조를 여러 번 사용해야 하는 큰 객체를 다룰 때 유용하며, 깊은 복사는 원본 객체에 의존하지 않는 새로운 객체를 생성할 때 유용합니다.

반응형