Shallow copy

개발(공부) 자국·2021년 4월 25일
0

얕은 복사는 shallow copy로 원본을 변하지 않게하는 복사를 말한다.

우선 참조자료형의 경우는 원시자료형과 다르게 참조값(주소값)이 변수에 담기게 된다.

원시 자료형은 재할당이 아니고서는 원래 담겨있는 데이터를 수정할 수 없다.

그에 반해 참조자료형 함수, 배열, 객체는 요소의 추가 제거로 변화가 생긴다.

문제는 그 참조자료형은 다른 변수에 할당을 해도 참조값만 할당이 되어

결국 두 변수에 담긴 참조자료형은 같은 객체나 배열, 함수를 사용하게 된다.

그래서 같은 참조값을 가지고 있는 어느 한쪽에서 추가 또는 삭제가 또는 재할당이 되면

다른 변수도 같은 영향을 받게 된다.

그렇다보니 같은 참조자료형을 사용하는 것이 아닌 요소의 값이 같고 영향이

없는 복사를 해야하는 경우가 생기게 된다.

이때 요소 값은 같지만 참조값이 다른 새로운 참조자료형을 만드는 것이

얕은 복사 shallow copy 이고 일반적으로 생각하는 복사와 비슷하다.

그런데 복사면 복사인 것이지 왜 얕은 복사라고 하는가 하면

문제는 복사를 하는 참조자료형의 형태가 배열인 경우는 [1, 2, [3, 4], 5, 6]

이런 형태의 배열이거나 객체인 경우는 { a:1, b:{ c: 3, d: 4}, e: 5}

이런 형태의 참조자료형 안에 참조자료형이 있는 경우는 문제가 된다.

참조자료형은 참조값을 변수에 담고 있는데 얕은 복사는 배열의 경우는 인덱스,

객체의 경우는 속성을 모두 찾아서 그 인덱스나 속성에 있는 값들을 하나하나복사해서

새로운 참조자료형의 주소를 만들어 다시 보관하는 절차를 진행한다.

참조자료형 안에 참조자료형이 없으면 우리가 생각하는 완벽한 복사가 된다.

하지만 참조자료형안에 참조자료형이 있으면 그렇지 못하게 된다.


예를 들어 배열 arr1 있다고 가정할 때 

let arr1 = [1, 2, [3, 4], 5, 6];

let arr2 = arr1.slice();

let arr3 = [1, 2, 3, 4, 5, 6];

let arr4 = arr3.slice();

[1, 2, [3, 4], 5, 6] 의 참조 값은 arr1에 담겨있다.

그리고 arr1[2] = [3, 4]로 되어 있지만 [3, 4]도 참조자료이기 때문에 그 참조값이

arr1[2] 인덱스 값에 담기게 된다.

그런데 복사된 새로운 배열 arr2는 arr1과는 요소 값은 같지만 다른 주소값을 가진

다른 배열이다. 그런데 복사하면서 arr1[2]의 값을 복사해 갈때 주소값을 복사해 갔기 때문에

arr1[2]의 값과 arr2[2]의 값은 같은 주소값을 가지는 [3, 4]는 같은 배열이 된다.

[3, 4]를 제외한 곳은 모두 다른 배열이지만 [3, 4]는 같은 배열을 사용하게 된다.

이렇게 모든 요소를 깊게 다 복사하지 못하기 때문에 얕은 복사라고 한다.

arr3 과 arr4는 완전히 같은 값을 가진 다른 배열이 된다.

얕은 복사를 하는 방법은 여러가지가 있다.

하지만 깊은 복사는 Javascript 내장함수로는 아직 지원하는 메소드가 없다고 한다.

더 많이 공부해서 알게 되면 그 이유도 해결방안도 이해할 수 있게 되지 않을까 싶다.

profile
기록을 중요하게 생각하는 사람입니다. 학습한 내용을 정리한 것이라 잘못된 정보가 있을 수 있습니다. 잘못된 정보는 언제든 말씀해 주시기 바랍니다.

0개의 댓글