JavaScript에서 배열을 딥 클론하는 방법
18305 단어 webdevcodenewbiejavascriptbeginners
어레이 복제에는 얕은 복제와 깊은 복제의 두 가지 유형이 있습니다. 얕은 복사본은 배열의 첫 번째 수준만 다루고 나머지는 참조됩니다. 중첩 배열의 진정한 복사본을 원한다면 딥 클론이 필요합니다. 딥 클론의 경우 JSON 방식을 사용하거나 Lodash를 사용하는 것이 더 좋습니다 👍
const numbers = [1, [2], [3, [4]], 5];
// Using JavaScript
JSON.parse(JSON.stringify(numbers));
// Using Lodash
_.cloneDeep(numbers);
배열은 참조 유형입니다.
두 가지 유형의 복제가 있는 이유를 이해하기 위해. 기본 사항을 자세히 살펴보고 참조 유형이 무엇인지 설명하겠습니다.
기본 유형(예: 숫자 또는 문자열)과 달리 배열은 참조 유형입니다. 즉, 배열을 변수에 할당할 때 실제 배열 자체가 아니라 메모리 주소를 할당하는 것입니다. WTH 😱. 나는 이것이 약간 혼란 스럽다는 것을 압니다. 그럼 예를 들어 설명해 보겠습니다.
값 유형 복사
그래서 여기에 큰 문제는 없습니다.
value
의 복사본을 만들고 있습니다. 그리고 valueCopy
를 변경해도 원본value
에는 영향을 미치지 않습니다. 의미가 있습니다. 사본을 변경할 때 원본에 전혀 영향을 미치지 않아야 합니다. 여기 다 좋아요👍let value = 3;
let valueCopy = value; // create copy
console.log(valueCopy); // 3
// Change valueCopy
valueCopy = 100
console.log(valueCopy); // 100
// ✅ Original NOT affected
console.log(value); // 3
참조 유형 복사
자, 이제 상황이 이상해집니다. 값 유형을 복사할 때와 동일한 방법을 사용하여 배열을 복사해 보겠습니다.
let array = [1,2,3];
let arrayCopy = array; // create copy
console.log(arrayCopy); // [1,2,3];
// Change 1st element of the array
arrayCopy[0] = '👻';
console.log(arrayCopy); // [ '👻', 2, 3 ]
// ❌Original got affected
console.log(array); // [ '👻', 2, 3 ]
원래 어레이도 영향을 받은 이유는 무엇입니까? 복사한 것은 배열 자체가 아니라 배열이 차지하는 메모리 공간에 대한 포인터이기 때문입니다. 참조 유형은 값을 보유하지 않으며 메모리의 값에 대한 포인터입니다.
참조 유형 복사에 대한 솔루션
따라서 해결책은 포인터가 아닌 값을 복사하는 것입니다. 이와 같이:
let array = [1,2,3];
let arrayCopy = [...array]; // create TRUE copy
console.log(arrayCopy); // [1,2,3];
// Change 1st element of the array
arrayCopy[0] = '👻';
console.log(arrayCopy); // [ '👻', 2, 3 ]
// ✅ Original NOT affected
console.log(array); // [ 1, 2, 3 ]
얕은 대 딥 클론
확산
...
을 사용하여 배열을 복사할 때 얕은 복사본만 생성합니다. 배열이 중첩되거나 다차원이면 작동하지 않습니다. 한 번 보자:let nestedArray = [1, [2], 3];
let arrayCopy = [...nestedArray];
// Make some changes
arrayCopy[0] = '👻'; // change shallow element
arrayCopy[1][0] = '💩'; // change nested element
console.log(arrayCopy); // [ '👻', [ '💩' ], 3 ]
// ❌ Nested array got affected
console.log(nestedArray); // [ 1, [ '💩' ], 3 ]
보시다시피 얕거나 첫 번째 레이어가 좋습니다. 그러나 중첩된 요소를 변경하면 원래 배열도 영향을 받습니다. 따라서 해결책은 딥 클론을 수행하는 것입니다.
let nestedArray = [1, [2], 3];
let arrayCopy = JSON.parse(JSON.stringify(nestedArray));
// Make some changes
arrayCopy[0] = '👻'; // change shallow element
arrayCopy[1][0] = '💩'; // change nested element
console.log(arrayCopy); // [ '👻', [ '💩' ], 3 ]
// ✅ Nested array NOT affected
console.log(nestedArray); // 1, [ 2 ], 3 ]
커뮤니티 입력
JSON과 호환되지 않는 값
: JSON 솔루션은 정말 조심해야 합니다! JSON과 호환되지 않는 값으로는 작동하지 않습니다. 이러한 데이터로 작업해야 하는 경우 라이브러리 기능 사용을 고려하십시오.
function nestedCopy(array) {
return JSON.parse(JSON.stringify(array));
}
// undefineds are converted to nulls
nestedCopy([1, undefined, 2]) // -> [1, null, 2]
// DOM nodes are converted to empty objects
nestedCopy([document.body, document.querySelector('p')]) // -> [{}, {}]
// JS dates are converted to strings
nestedCopy([new Date()]) // -> ["2019-03-04T10:09:00.419Z"]
deepClone 대 JSON
: deepClone과 JSON.stringify/parse 간에 약간의 차이가 있음을 알려드립니다.
JSON.stringify/parse는 함수 또는 기호 속성이 없는 숫자, 문자열 및 개체 리터럴에서만 작동합니다.
deepClone은 모든 유형, 함수 및 기호에 대한 작업을 참조로 복사합니다.
예를 들면 다음과 같습니다.
const lodashClonedeep = require("lodash.clonedeep");
const arrOfFunction = [() => 2, {
test: () => 3,
}, Symbol('4')];
// deepClone copy by refence function and Symbol
console.log(lodashClonedeep(arrOfFunction));
// JSON replace function with null and function in object with undefined
console.log(JSON.parse(JSON.stringify(arrOfFunction)));
// function and symbol are copied by reference in deepClone
console.log(lodashClonedeep(arrOfFunction)[0] === lodashClonedeep(arrOfFunction)[0]);
console.log(lodashClonedeep(arrOfFunction)[2] === lodashClonedeep(arrOfFunction)[2]);
재귀 사용
Tareq Al-Zubaidi : 이 문제에 대한 또 다른 간단하고 성능이 뛰어난 솔루션이 있습니다. 나는 이것을 해결하기 위해 재귀를 사용할 것입니다.
const clone = (items) => items.map(item => Array.isArray(item) ? clone(item) : item);
비교 테스트 참조here
자원
읽어주셔서 감사합니다 ❤
안녕하세요! | | Facebook | Medium | Blog
Reference
이 문제에 관하여(JavaScript에서 배열을 딥 클론하는 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/samanthaming/how-to-deep-clone-an-array-in-javascript-3cig텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)