🔥 배열의 복사
다시 얘기하지만 배열은 참조 자료형 데이터 타입이다.
자바스크립트에서 기본 데이터 타입(원시 타입)으로는
string, number, null, undefined, symbol이 존재한다.
참조형 데이터 타입으로는 Array와 Object가 존재한다.
사본을 만들어내지 않고 원본을 참조하도록 복사한 척을 하는 것
기본 데이터 타입에서 복사한 데이터를 변경할 때 원본은 변경되지 않는다.
var a = 10;
var b = a; // (1)
console.log(a); // 10
console.log(b); // 10
b = 5; // (2)
console.log(a); // 10
console.log(b); // 5
(1)
두 변수는 서로 같은 주솟값(@5003)을 참조
(2)
원본의 주소(@5003)를 참조하고 있었지만 새로운 데이터로 변경할 때 데이터 영역에서 새로운 데이터를 할당하고(@5004) 그 주솟값을 다시 참조
var arr1 = [1, 2, 3, 4];
var arr2 = arr1; // (1)
console.log(arr1); // [1, 2, 3, 4]
console.log(arr2); // [1, 2, 3, 4]
arr2[0] = 0; // (2)
console.log(arr1); // [0, 2, 3, 4]
console.log(arr2); // [0, 2, 3, 4]
(1)
두 변수는 서로 같은 주솟값(@5003)을 참조
@5003에 데이터를 저장하려고 보니 여러 개의 프로퍼티로 이뤄진 데이터 그룹이다. 이 그룹 내부의 프로퍼티들을 저장하기 위해 별도의 변수 영역을 마련하고, 그 영역의 주소 @7001 ~ ?를 @5003에 저장
(2)
arr2 가 arr1 과 같은 값을 참조하고 있기 때문에 사본인 arr2 에서 배열의 요소를 수정했을 때 원본에도 수정이 일어남.
@5002가 참조하는 값중 @7001의 값의 주소가 바뀜.
arr1, arr2는 같은 주솟값 @5002를 참조함.
이때 @5004의 값인 1은 참조 카운트가 0인 메모리 주소기 때문에 가비지 컬렉터의 수거 대상이 됨.
완벽하게 원본과 사본을 나눠 복사하는 방법
let arr1 = [1, 2, 3];
let arr2 = [...arr1];
arrB[0] = 10;
console.log(arr1); // [1, 2, 3]
console.log(arr2); // [10, 2, 3]
한단계 까지의 깊은 복사만 적용. (다차원 배열X)
두단계 이상의 depth부터는 참조 값을 전달하는 얕은복사를 진행함.
다차원 배열을 복사해야 하는 경우 JSON.stringify() 함수로 원본 배열을 문자열로 변환 후 JSON.parse() 함수로 JavaScript Object로 파싱 한다.
let arr1 = [[1, 2, 3], ['A', 'B', 'C']];
let arr2 = JSON.parse(JSON.stringify(arr1));
arrB[0][0] = 10;
console.log(arrA); // [[1, 2, 3], ['A', 'B', 'C']]
console.log(arrB); // [[10, 2, 3], ['A', 'B', 'C']]
완전한 깊은 복사를 반드시 해야 하는 경우라면, node.js 환경에서 외부 라이브러리인 lodash, 또는 ramda를 설치하면 된다. 다음은 lodash의 cloneDeep을 사용한 깊은 복사의 예시이다.
const lodash = require('lodash');
const arr = [1, 2, [3, 4]];
const copiedArr = lodash.cloneDeep(arr);
console.log(arr); // [1, 2, [3, 4]]
console.log(copiedArr); // [1, 2, [3, 4]]
console.log(arr === copiedArr) // false
console.log(arr[2] === copiedArr[2]) // false
.slice() // 주소가 다르기 때문에 복사한 배열에 요소를 추가해도 원본 배열에는 변화x
얕은 복사를 하지만 새로운 배열을 만드는 아이들이 많은것같은데... 이 부분에 대해서는 공부를 많이 해봐야겠당...🫥🫥🫥