HOWTO · JavaScript

JavaScript에서 객체 복사

이 기사에서는 JavaScript에서 객체의 복사본을 만드는 방법을 살펴보겠습니다.

이 페이지의 내용

다양한 프로그래밍 언어에는 메모리에 데이터를 구성하고 저장할 수 있는 다양한 데이터 구조가 있습니다. 각 데이터 구조는 고유하게 작동합니다. 예를 들어, C++ 및 Java에는 데이터를 키-값 형식으로 저장하는 Hashmap이 있습니다. 마찬가지로 JavaScript에는 키-값 형식으로 데이터를 저장할 수 있는 객체라는 데이터 구조가 있습니다.

개체는 데이터에 액세스할 때 유용합니다. 키를 사용하여 객체 내의 모든 데이터에 쉽게 액세스할 수 있습니다. 이 기사에서는 JavaScript에서 객체를 복사할 수 있는 다양한 방법을 볼 것입니다.

JavaScript 객체는 변경 가능하며 참조로 저장됩니다. 이미 객체를 생성했고 다른 객체에 할당하려는 경우 해당 객체는 이제 이 객체의 주소를 보유합니다. 객체의 참조를 다른 객체 내부에 저장하고 있기 때문에 이 새 객체를 사용하여 원래 객체 내부에 있는 값을 쉽게 변경할 수 있습니다.

var a = {'name': 'Adam', 'company': 'Google'}

var b = a;
b.name = 'Sam'

console.log(a.name, b.name);

출력:

Sam Sam

위의 예에서 볼 수 있듯이 한 개체를 다른 개체에 할당해도 개체 자체는 복사되지 않습니다. 이전 개체의 주소만 새 개체에 저장합니다.

JavaScript에서 객체를 복사하는 방법에는 두 가지가 있습니다. 한 가지 방법을 얕은 복사라고 하고 다른 방법을 깊은 복사라고 합니다. 이러한 방법을 구현하기 위해 다음과 같이 일부 JavaScript 메서드를 사용할 수 있습니다.

JavaScript에서 객체를 얕은 복사하기

얕은 복사에서는 개체의 첫 번째 수준에 있는 키-값 쌍만 새 개체에 복사됩니다. 그리고 배열이나 내부의 다른 객체와 같은 모든 중첩 요소 또는 속성은 복사되지 않고 대신 해당 참조가 이 객체에 저장됩니다.

얕은 복사에서는 원본 개체의 일부 속성도 영향을 받습니다. 이를 이해하려면 아래 예를 참조하십시오.

var obj1 = {
  'firstName': 'James',
  'lastName': 'Bond',
  'films': ['No Time To Die', 'Spectre', 'Skyfall', 'Quantum of Solace'],
  'actors':
      {'characters': {'realName': 'Daniel Craig', 'fakeName': 'James Bond'}}
}

이 예에는 obj1이라는 객체가 있습니다. JavaScript를 사용하여 이 객체를 단순 복사하려면 Object.assign() 및 스프레드 연산자 ...를 사용할 수 있습니다. JavaScript에서 아래 메소드를 사용하여 obj1에 대해 얕은 복사를 수행해 보겠습니다.

  1. Object.assign() 메서드

Object.assign() 메서드는 두 개의 매개변수를 사용합니다. 첫 번째 매개변수는 복사가 완료된 후 반환될 target 객체입니다. 두 번째 매개변수는 복사하려는 객체 obj1입니다. 이 경우에는 빈 객체 {}를 대상으로 전달합니다. obj1 내부의 모든 요소가 이 빈 개체에 복사되기 때문입니다. 복사가 완료되면 Object.assign()obj2 변수 안에 저장할 새 개체를 반환합니다.

var obj2 = Object.assign({}, obj1);

나중에 이 객체의 속성을 수정하고 왜 이것을 얕은 복사본이라고 하는지 실제로 보게 될 것입니다.

obj2.firstName = 'Camila';
obj2.films[0] = 'abcccc';
obj2.actors.characters.realName = 'Camila';

console.log(obj1);
console.log(obj2);

출력:

object.assign() 메서드를 사용하여 자바스크립트에서 shalow 복사

여기에서 obj2, firstName, films[] 배열의 첫 번째 영화, actors.characters 객체의 realName 속성을 사용하여 세 가지 값을 변경합니다. 그런 다음 두 개체를 모두 인쇄합니다.

위 이미지는 두 객체 모두 firstName 속성만 변경되지 않았음을 보여줍니다. 다른 두 속성 films[]realName은 두 개체에서 모두 변경됩니다. firstName 속성이 고유하기 때문에 이것을 얕은 복사라고 하는 반면, 여기에 주소를 저장할 때 다른 속성은 두 개체에 모두 공통입니다. 여기에서 첫 번째 수준에 있는 속성만 복사됩니다.

  1. 스프레드 연산자(...)

나머지 연산자는 obj1의 속성을 obj2로 복사합니다. 이것은 객체의 속성을 얕은 복사하는 Object.assign()과 ​​유사합니다. 스프레드 연산자를 사용하여 개체를 복사하려면 스프레드 기호 뒤에 개체 이름을 작성해야 합니다.

var obj2 = {...obj1};

obj2.firstName = 'Camila';
obj2.films[0] = 'abcccc';
obj2.actors.characters.realName = 'Camila';

Object.assign() 메서드를 사용한 후 얻은 것과 동일한 출력을 얻을 수도 있습니다.

JavaScript의 객체 딥 카피

전체 복사에서는 모든 키-값 쌍이 새 개체에 복사됩니다. 깊은 복사를 수행하기 위해 JSON.parse()JSON.stringify() 메서드를 사용할 수 있습니다. 깊은 복사는 프로토타입 개체 내부에 있는 속성을 복사하지 않습니다.

JSON.stringify()를 사용하여 먼저 전체 개체(이 경우 obj1)를 문자열로 변환한 다음 나중에 JSON.parse() 메서드를 사용하여 구문 분석합니다. 이 문자열을 JSON 형식으로 다시 변환합니다.

let obj2 = JSON.parse(JSON.stringify(obj1));

여기에서 obj1 내부의 속성에 영향을 주지 않는 obj2 내부의 모든 속성을 수정할 수 있습니다.

obj2.firstName = 'Camila';
obj2.films[0] = 'abcccc';
obj2.actors.characters.realName = 'Camila';

출력:

JavaScript에서 객체 딥 카피

우리는 이전에 수정했던 것과 동일한 값을 수정하고 있으며 이제 obj2의 속성을 변경할 때 obj1의 속성에 영향을 주지 않는다는 것을 알 수 있습니다.