[개발 공부]/[자바스크립트]

[자바스크립트] 기본형과 참조형의 차이 / 깊은복사 & 얕은복사

wild keyboardist 2022. 6. 2. 14:43

[자바스크립트] 기본형과 참조형의 차이 / deep copy & shallow copy

 

 

 

 

 

 

 

 

 

[요점정리]

 

 

기본형변수를 할당한 후, 해당 저장소에  저장하며, 

참조형은 변수를 할당한 후, 해당 저장소에 주소를 저장한다.

 

 

이런 차이점으로 인하여, 

기본형은 복사 후 원본값이 변경될 경우, 복사본의 값은 변하지 않고 그대로인 반면,

참조형은 복사 후 원본값이 변경될 경우, 서로가 참조하고 있는 주소값이 같은므로, 

원본값과 복사본의 값이 둘다 변경된다.

 

 

 

 

여기서 깊은복사(deep copy) 와 얕은복사(shallow copy)가 구별된다.

 

 

 

 

 

 

 

 

 

 

[데이터의 구조]

 

 

 

1) 기본형(primitive type) : String, Number, Boolean, Null, Undefined, Symbols

 

 

 

기본형은 하나의 저장소가 하나의 메모리를 참조한다.

 

// 초기 Stack 저장소
// [가] [나] [다] [라] [마] [바] [사]
// [아] [자] [차] [카] [타] [파] [하]


var name = "노평례";


// [가] ["노평레"] [다] [라] [마] [바] [사]
// [아] [자] [차] [카] [타] [파] [하]



name = "디즈니";


// [가] ["디즈니"] [다] [라] [마] [바] [사]
// [아] [자] [차] [카] [타] [파] [하]

 

 

 

[나] 라는 저장소를 name 이라고 명명하고, 저장한다.

이후, "노평례"를 할당하면,

name 은 "노평례" 값을 저장한다.

 

 

 

 

이후, name 에 새로운 값, "디즈니"를 할당하면,

name 은 [나] 라는 저장소에 이미 자리 잡았으므로 그대로 두고,

 

1) [나] 저장소, 즉 name 을 확인

2) name 의 값 = "노평례"

3) "노평례" 를 지우고, 신규값 "디즈니"를 저장한다.

 

 

 

 

 

 

 

여기서 name 을 복사하여 name2 를 만들어낸다면, name 값의 변화는 두 변수에 어떤 영향을 미칠까?

 

var name = "노평례";
var name2 = name;


// name  = [나] 저장소
// name2 = [하] 저장소
// [가] ["노평례"] [다] [라] [마] [바] [사]
// [아] [자] [차] [카] [타] [파] ["노평례"]



name = "디즈니";

// name2 의 값은 변경없음
// [가] ["디즈니"] [다] [라] [마] [바] [사]
// [아] [자] [차] [카] [타] [파] ["노평례"]

 

 

 

두 변수는 서로 다른 메모리를 바라보고 있으므로,

원본인 name 값의 변경은 name2 값에 영향을 주지 않는다!

 

 

 

 

 

 

 

 

 

 

 

 

 

2) 참조형(reference type) : Array, Object, Functions, Collections, Dates, etc 

 

 

 

참조형 또한 하나의 저장소가 하나의 메모리를 참조한다.

그러나 값이 아닌, 주소를 저장한다. 

 

// 초기 Stack 저장소
// [가] [나] [다] [라] [마] [바] [사]
// [아] [자] [차] [카] [타] [파] [하]

// 초기 Heap 저장소
// [1] [2] [3] [4]
// [5] [6] [7] [8]


var temp = ["노평례", "디즈니", 100];


// Stack 저장소
// [가] [temp] [다] [라] [마] [바] [사]
// [아] [자] [차] [카] [타] [파] [하]

// Heap 저장소
// [1] [2] [3] [4]
// [5] ["노평례"] ["디즈니"] [100]

 

 

 

[나] 라는 저장소에 temp의 값을 바로 할당하는 게 아니고, temp 가 참조할 주소들을 저장한다.

=>  Heap 저장소의 [6], [7], [8] 이 되겠다.

 

1) [나] 저장소, 즉 temp 를 확인

2) temp 의 값 = [6], [7], [8] 의 주소값

3) [6] 에는 "노평례"

4) [7] 에는 "디즈니"

5) [8] 에는 100

 

 

 

 

즉, 참조형은 Stack 저장소에 참조할 주소 값만을 가지고 있고, 

객체 자체의 내용은 Heap 저장소에 가지고 있다.

 

 

 

 

 

여기서 기본형과의 차이점이 나온다.

만약 obj 를 복사하여 obj2 를 만들어낸다면, obj 값의 변화는 두 변수에 어떤 영향을 미칠까?

 

var obj = {
    name : 'Son',
    age : 30
};

var obj2 = obj;


// obj 의 요소만 변경
obj.age = 21;


// 결과값 :
// obj  => {name : 'Son', age : 21}
// obj2 => {name : 'Son', age : 21}

 

 

 

두 변수는 동일한 주소값을 바라보고 있으므로,

원본인 obj 값의 변화는 obj2 값도 변경시킨다!

(값을 바라보는게 아니라, 주소를 바라보고 있으므로)

 

 

 

 

 

 

 

 

 

 

[깊은복사와 얕은복사의 차이]

 

 

 

위에서 보았듯, 기본형은 깊은복사/얕은복사가 중요하지않다.

문제가 되는건 참조형이다.

 

 

 

 

참조형의 얕은 복사는 원본의 주소를 공유하고 있기에 원본값의 변경이 복사본의 변경으로 이어지지만,

깊은 복사의 원리는 원본의 값을 복사하는 것을 물론, 이를 새로운 주소값으로 따로 분리해내는 것이다.

 

 

 

 

 

 

 

 

 

 

AngularJS 와 Javascript 로 깊은복사하는 방법을 알고싶다면?

https://devinserengeti.tistory.com/40?category=901018

 

[AngularJS] Angular.copy() - 깊은복사하기

[AngularJS] AngulrJS 깊은복사 vs Javascript 로 깊은복사 깊은복사와 얕은복사의 차이점은 모두 안다고 가정하고, AngularJS 에서 깊은복사하는 법과 Plain Javascript 로 깊은복사하는 법만 간략히 정리해본다

devinserengeti.tistory.com