… 각 객체에는 동일한 배열 내의 다른 객체에 대한 참조가 있습니까?
내가 처음이 문제를 생각해 냈을 때
var clonedNodesArray = nodesArray.clone()
존재하고 자바 스크립트에서 객체를 복제하는 방법에 대한 정보를 검색했습니다. 나는 StackOverflow에 관한 질문 을 찾았으며 (매우 동일한 @JohnResig에 의해 답변 됨) jQuery를 사용하면 할 수 있다고 지적했습니다.
var clonedNodesArray = jQuery.extend({}, nodesArray);
객체를 복제합니다. 나는 이것을 시도했지만, 이것은 배열에있는 객체의 참조 만 복사합니다. 만약 내가
nodesArray[0].value = "red"
clonedNodesArray[0].value = "green"
nodesArray [0] 및 clonedNodesArray [0]의 값이 모두 “green”으로 나타납니다. 그런 다음 시도했습니다
var clonedNodesArray = jQuery.extend(true, {}, nodesArray);
깊게 객체를 복사하지만 Firebug와 Opera Dragonfly에서 각각 ” 너무 많은 재귀 “와 ” 제어 스택 오버플로 “메시지를 받았습니다.
어떻게 하시겠습니까? 이조 차도해서는 안되는 일입니까? Javascript에서 재사용 가능한 방법이 있습니까?
답변
얕은 복사본의 문제는 모든 개체가 복제되지 않는다는 것입니다. 각 객체에 대한 참조는 각 배열에서 고유하지만 궁극적으로 객체를 가져 오면 이전과 동일한 객체를 처리하게됩니다. 복제 방법에는 아무런 문제가 없습니다. Array.slice ()를 사용하여 동일한 결과가 발생합니다.
딥 카피에 문제가있는 이유는 순환 객체 참조로 끝나기 때문입니다. 딥은 가능한 한 깊게 진행되며 원이 있으면 브라우저가 사라질 때까지 계속 무한대로 진행됩니다.
데이터 구조를 유향 비순환 그래프로 표현할 수 없다면, 심층 복제를위한 다목적 방법을 찾을 수 있을지 모르겠습니다. 순환 그래프는 많은 까다로운 코너 사례를 제공하며 일반적인 작업이 아니기 때문에 모든 사람이 완전한 솔루션을 작성했다고 의심합니다. 이 페이지에서이 문제에 대한 좋은 의견을 찾았습니다 .
순환 참조가있는 객체 배열의 깊은 사본이 필요한 경우 다중 데이터 복제와 같이 특수한 데이터 구조를 처리하기 위해 고유 한 방법을 코딩해야한다고 생각합니다.
- 첫 번째 라운드에서는 배열의 다른 객체를 참조하지 않는 모든 객체를 복제합니다. 각 객체의 원점을 추적합니다.
- 두 번째 라운드에서 객체를 서로 연결하십시오.
답변
객체에 JSON 직렬화 가능 콘텐츠 (함수, 아니오 Number.POSITIVE_INFINITY
등)가 포함되어 있으면 배열이나 객체를 복제하기 위해 루프가 필요하지 않습니다. 다음은 순수한 바닐라 단선 솔루션입니다.
var clonedArray = JSON.parse(JSON.stringify(nodesArray))
아래 주석을 요약하면이 방법의 주요 장점은 배열 자체뿐만 아니라 배열의 내용도 복제한다는 것입니다. 주요 단점은 JSON 직렬화 가능 콘텐츠에 대한 작업의 한계이며 성능입니다 ( slice
기반 접근 방식 보다 훨씬 나쁩니다 ).
답변
Object.assign을 사용 하여 객체 배열 복제를 해결했습니다.
const newArray = myArray.map(a => Object.assign({}, a));
스프레드 구문으로 더 짧거나
const newArray = myArray.map(a => ({...a}));
답변
얕은 사본 만 있으면 정말 쉬운 방법은 다음과 같습니다.
new_array = old_array.slice(0);
답변
이 복제를 수행하는 가장 좋은 방법은 다음과 같습니다.
사용하여 ...
ES6 확산 연산자를.
가장 간단한 예는 다음과 같습니다.
var clonedObjArray = [...oldObjArray];
이런 식으로 배열을 개별 값으로 분산시키고 [] 연산자를 사용하여 새 배열에 넣습니다.
작동 방식을 보여주는 더 긴 예는 다음과 같습니다.
let objArray = [ {a:1} , {b:2} ];
let refArray = objArray; // this will just point to the objArray
let clonedArray = [...objArray]; // will clone the array
console.log( "before:" );
console.log( "obj array" , objArray );
console.log( "ref array" , refArray );
console.log( "cloned array" , clonedArray );
objArray[0] = {c:3};
console.log( "after:" );
console.log( "obj array" , objArray ); // [ {c:3} , {b:2} ]
console.log( "ref array" , refArray ); // [ {c:3} , {b:2} ]
console.log( "cloned array" , clonedArray ); // [ {a:1} , {b:2} ]
답변
이것은 나를 위해 작동합니다 :
var clonedArray = $.map(originalArray, function (obj) {
return $.extend({}, obj);
});
그리고 배열에 객체의 깊은 사본이 필요한 경우 :
var clonedArray = $.map(originalArray, function (obj) {
return $.extend(true, {}, obj);
});
답변
$.evalJSON($.toJSON(origArray));