Shallow copy 와 Deep copy

김효성·2022년 8월 30일
0

깊은 복사, 얕은 복사

간단히 말하자면 얕은 복사는 객체의 참조값(주소값)을 복사하고, 깊은 복사는 객체 실제 값을 복사한다.

자바스크립트에는 원시값과 참조값 두가지 데이터 타입이 존재한다.

  • 원시값은 기본 자료형 데이터이다. Number, String, Bollean, Null, Undefined 등이 해당한다. 변수에 원시값을 저장하면 변수의 메모리 공간에 실제 데이터 값이 저장되고, 할당된 변수를 조작하려고 하면 저장된 셀지 값이 조작이된다.

  • 참조값은 여러 자료형을 구성되는 메모리에 저장된 객체이다. Object, Symbol 등이 해당한다. 변수에 객체를 저장하면 독립적인 메모리 공간에 값을 저장하고, 변수에 저장된 메모리 공간을 참조하여 저장하게 된다. 그래서 할당된 변수를 조작하는 것은 객체를 조작하는것이 아닌 객체의 참조값을 조작하는 것이다.

    원시값을 복사할 때 그 값은 또다른 독립적인 메모리 공간에 할당하기 때문에 복사를 하고 값을 수정해도 원시값을 저장한 변수에는 영향을 끼치지 않는다. 이처럼 실제 값을 복사하는 것을 깊은 복사라고 한다.

const a = 'a'
const b = 'b';

b = 'c';

console.log(a); //'a';
console.log(b); //'c';

//기존 값에 영향을 끼치지 않는다 ====> 깊은 복사!


const a = {  one: 1,  two: 2,};

let b = a;

b.one = 3; 

console.log(a); // { one: 3, two: 2 } 출력
console.log(b); // { one: 3, two: 2 } 출력 

// 기존 값에 영향을 끼친다.

주의할점은 배열의 slice메소드 이다.
얼핏보면 배열을 깊은 복사한거로 생각할수 있지만 얕은 복사이다.
console.log(arr === arr1)을 찍어보면 false가 출력되는 걸 볼수있다.

깊은 복사와 얕은 복사 차이의 중요성

이 두개의 개념이 중요한 이유는 변수 값에 접근할 때 차이가 있기 때문이다.

let studyGroup = ['김효성', '허신애', '위정우', '이경은']

let newStudyGroup = studyGroup 

newStudyGroup[0] = '성종화'

console.log(newStudyGroup) // ['성종화', '허신애', '위정우', '이경은']
console.log(studyGroup) // ['성종화', '허신애', '위정우', '이경은']

위와 같이 출력되는 이유는 객체(배열)은 참조값을 복사하게 되므로 얕은 복사가 이루어진다. 그래서 기존 원본 값에도 영향을 미치게 된다. 원본을 건드리지 않고 데이터를 수정해야 하는 경우 깊은 복사를 통해 작업을 해야한다.

그런 경우 JSON.parse && JSON.stringify 메소드를 통해 복사를 하거나 재귀함수를 구현한 복사, Lodash라이브러리를 사용하면 깊은 복사가 가능하다.

하지만 [...arr] 문법으로도 깊은 복사가 가능한것 같다.
[...arr] 문법을 쉽게쓰면 arr 배열의 값의 대괄호를 풀고 새로운 배열로 만들어 주는 것 이라고 이해하면 될거같다. 따라서 위의 문제점은 아래와 같이 해결할 수 있다.

let studyGroup = ['김효성', '허신애', '위정우', '이경은']

let newStudyGroup = [...studyGroup] 

newStudyGroup[0] = '성종화'

console.log(newStudyGroup) // ['성종화', '허신애', '위정우', '이경은']
console.log(studyGroup) // ['김효성', '허신애', '위정우', '이경은']

현업에서는 원본데이터는 건드리지 않고 작업을 할 것이기 때문에 위 같은 Data Reference 의 원리를 이해하는게 중요할 것 같다.

profile
인생은 단방향 디자인 패턴 🏃

0개의 댓글