JavaScript에서 개체 딥 클론
JavaScript는 객체의 언어입니다. 거의 모든 것이 JavaScript의 객체입니다. 부울, 숫자, 문자열, 날짜, 수학, 정규식, 배열, 함수 및 객체 자체는 모두 객체입니다. 다양한 속성과 메소드로 구성된 키-값 쌍의 모음입니다. 이들은 메모리에 직접 저장되며 참조로만 복사 할 수 있습니다. 변수는 개체를 저장하지 않고 메모리에 해당 개체에 대한 참조 만 저장합니다. 따라서 개체 변수를 복사하려고하면 동일한 개체에 대한 추가 참조가 생성됩니다. 이 방법을 단순 복사라고합니다. 원본 오브젝트의 변경 사항이 복제본에 영향을주지 않도록하는 것은 이상적이지 않습니다. 이로 인해 객체를 심층 복제하는 방법이 필요합니다. 이 튜토리얼에서는 JavaScript에서 객체를 딥 복제하는 방법을 설명합니다.
얕은 복사와 전체 복사
단순 복사본은 개체의 비트 복사본입니다. 생성 된 새 객체는 숫자, 부울 및 문자열과 같은 기본 요소를 성공적으로 복사하지만 객체에 대한 참조는 복사하지 않습니다. 참조 주소 만 동일한 개체를 가리키는 포인터가됩니다. 원본 개체의 모든 변경 사항은 단순 복사본에 반영됩니다.
반면에 전체 복사는 원본 개체에 대한 주소 / 참조 만 복사하는 것이 아니라 전체 개체를 복사합니다. 생성 된 새 개체는 복사 된 개체에 대한 종속성이 없습니다. JavaScript는 객체를 복사하기위한 다양한 내장 메소드를 제공하지만 대부분의 경우 얕은 복사가 기본 동작입니다.
JavaScript의 얕은 복사 방법
얕은 복사 방법에 대해 간략하게 설명하여 딥 복사에 대한 잘못된 방법 중 일부를 알 수 있습니다.
Spread 구문을 사용하여 JavaScript에서 개체를 얕게 복제
새 개체를 만든 다음 스프레드 구문을 사용하여 개체 내부의 개체 내용을 자체적으로 열거하여 개체를 복제 할 수 있습니다. 올바른 방법처럼 보이지만 데이터의 얕은 사본을 생성합니다.
const obj = {
a: 1,
b: {c: 2}
}
const clone = {...obj}; // creates a shallow copy
obj.b.c = 5;
console.log(clone.b.c); // outputs 5
위의 코드에서spread
구문을 사용하여 객체의 얕은 사본을 만듭니다. 그런 다음 원본 개체에서 참조 된 개체의 속성 중 하나를 수정하고 복제 된 개체에서 속성이 수정되었음을 보여줍니다.
Object.assign()
을 사용하여 JavaScript에서 객체를 얕게 복제하려면
object.assign()
메소드는 객체의 단순 복사본을 새 객체 변수에 할당합니다. 대상과 소스의 두 가지 인수가 필요합니다. target
은 일반적으로 복사 할 빈 개체를 나타내는 데 사용되는 한 쌍의 빈 괄호입니다. 선택적 인수이지만 전달하면 원래 객체가 변경되지 않도록합니다. 두 번째 인수는 복사 할 개체입니다.
const obj = {
a: 1,
b: {c: 2}
}
const clone = Object.assign({}, obj); // creates a shallow copy
obj.b.c = 5;
console.log(clone.b.c); // outputs 5
위의 코드에서Object.assign()
을 사용하여 객체의 얕은 사본을 만듭니다. 그런 다음 원본 개체에서 참조 된 개체의 속성 중 하나를 수정하고 복제 된 개체에서 속성이 수정되었음을 보여줍니다.
JavaScript의 딥 복사 방법
JSON.parse()
및JSON.stringify()
를 사용하여 JavaScript에서 객체 딥 복제
JSON.stringify()
는 JavaScript 객체를 JSON 문자열로 변환하는 데 사용되며JSON.parse()
는 JSON 문자열을 JavaScript Object로 변환하는 데 사용됩니다. JSON.stringify()
주위에JSON.parse()
를 감싸서 먼저 JavaScript 객체를 JSON String으로 변환 한 다음 파싱하여 객체의 사본을 얻을 수 있습니다.
var user = {name: 'Harshit', age: 21, Profession: 'Software Engineer'};
let fakeDeepCopy = JSON.parse(JSON.stringify(user));
이 메서드는 기능이없는 개체에 대해서만 깊은 복사본을 만듭니다. 다른 참조 된 개체와 같은 순환 종속성에 문제가 있습니다. 복사 된 개체의 속성 순서도 원본 개체와 다를 수 있습니다. 따라서이 방법은 원시 데이터 유형이 거의없는 간단한 객체가있는 경우 좋은 속임수이지만 실제 환경에서는 권장되지 않습니다.
네이티브 딥 클로닝을 사용하여 JavaScript에서 객체 딥 클론
Node.js v8
모듈의 직렬화 알고리즘을 사용하여 객체를 딥 복제 할 수 있습니다. 특정 내장 데이터 유형으로 제한되지만 복제 된 데이터 내에서 참조를 보존합니다. 이를 통해 JSON 메서드에서 지원하지 않는 여러 순환 및 재귀 구조를 복사 할 수 있습니다.
const v8 = require('v8');
const structuredClone = obj => {
return v8.deserialize(v8.serialize(obj));
};
JSON 메서드의 문자열 화 및 구문 분석과 마찬가지로 객체를 역 직렬화 한 다음 직렬화합니다. 그러나 순환 종속성을 유지하고 약간 더 좋습니다.
Lodash 라이브러리를 사용하여 JavaScript에서 객체 딥 복제
Lodash 라이브러리에는 얕은 복사 및 전체 복사 기능, 즉clone
및clonedeep
이 있습니다. 완전한 라이브러리가 아닌 필요한 함수 만 가져올 수있는 훌륭한 라이브러리입니다. clonedeep
메소드는 값을 재귀 적으로 복사 한 다음 모든 개체 상속을 유지하여 개체의 실제 복사본을 만드는 방식으로 작동합니다.
const lodashClonedeep = require('lodash.clonedeep');
let obj = {a: 1, b: {c: 2}} let deepClone = lodashClonedeep(obj);
여기에서 lodash에서clonedeep
함수를로드하고이를 사용하여 객체를 딥 복제합니다. 잘 테스트되고 유지 관리되는 라이브러리이지만 Vanilla JavaScript가 아닌 Node.js에서만 사용할 수 있습니다.
jQuery extend()
메소드를 사용하여 JavaScript에서 객체를 딥 복제합니다
jQuery의.extend()
를 사용하여 객체를 얕게 복사하고 딥 복사 할 수 있습니다. 데이터 손실이나 데이터 손상이없는 가장 안정적인 딥 클로닝 방법입니다. 주요 기능은 둘 이상의 개체를 병합하는 것입니다. 그러나 오브젝트 복제에도 사용할 수 있습니다. 인수는[deep]
,target
,object1 ..... objectN
입니다.
[deep]
: 선택적 인수입니다. 허용되는 유일한 값은 true입니다. 함수에 전달되면 함수는 객체의 전체 복사본을 만듭니다. 그렇지 않으면 얕은 사본을 형성합니다.target
: 확장 할 개체입니다. 병합 된 모든 개체를받습니다.object1, ..., objectN
: 새 객체로 병합 / 복제 할 객체입니다.
let obj = {a: 1, b: {c: 2}} let shallowClone =
$.extend({}, obj); // creates a shallow copy
let deepClone = $.extend(true, {}, obj); // creates a deep copy
보다 분명한 해결책은 소스 객체의 모든 속성을 반복하여 새 객체로 복제하는 것입니다. 위에서 설명한 모든 방법은 모든 주요 브라우저와 호환됩니다.
Harshit Jindal has done his Bachelors in Computer Science Engineering(2021) from DTU. He has always been a problem solver and now turned that into his profession. Currently working at M365 Cloud Security team(Torus) on Cloud Security Services and Datacenter Buildout Automation.
LinkedIn