JS

#33가지 Javascript 필수 개념 - 3. Value Types, Reference Types

728x90

본 내용은 아래의 글을 참조하여 작성하였습니다

(https://github.com/leonardomso/33-js-concepts#3-value-types-and-reference-types)

 

 

 

* Pass By Value

 

앞선 게시글 JS 필수 개념 2 - Primitive Types (https://sdy-study.tistory.com/29) 에서도 언급했듯이, 

JS 의 기본 데이터 타입을 Primitive Types 라 부르고 이에 대한 타입이 총 5개가 존재한다고 했다

(ES6 이후 추가된 Symbol 은 일단 제외한다)

 

5개의 primitive types (Number, Null, Undefined, String, Boolean) 은 데이터를 처리할 때

값(value) 에 근거하여 변수에 변화를 준다.

 

무슨 말인가 하면,

var x = 10;
var y = 'a';
 
var a = x;
var b = y;
cs

 

위와 같은 4개의 변수를 선언했다고 가정해보자.

 

 

만약 변수 a, b 를 아래와 같이 다른 값으로 바꿨다고 치면,

= 999;
= 'Z';
cs

변수 x, y 의 값은 변할까?

 

프로그래밍을 처음 접하는 사람이 아니라면, 당연히 바뀌지 않는다고 말할 것이다.

그리고 실제로도 4개의 변수를 각각 출력하면 변수 a,b 만 변할 뿐 변수 x, y 는 변하지 않는다.

 

출력

 

그렇다면, 왜 변하지 않는 걸까?

이에 대한 이해를 하기 위해서는 JS 에서 Primitive Type 에 해당하는 변수를 

어떤 식으로 메모리에 저장하는지를 이해해야 한다.

 

 

 

* 메모리

 

위에서 선언한 4개 변수들은 메모리의 각자 다른 부분에 저장되기 때문이다.

실제 컴퓨터의 메모리는 다른 모습으로 나타나지만

간단하게 보면 위처럼 각자 다른 공간에서 저장된다.

처음에 a = x, b = y 할 때도 서로 다른 메모리 공간에서 저장되었기 때문에

a = 999; y = 'Z' 할 때도 값이 변하지 않았던 것이다.

 

 

그렇다면 모든 변수가 이런식으로 저장되는가? 는 아니다.

위와 같은 방식은 passed by value 로 처리된 것이고,

또 다른 방식으로 passed by reference 라는 방식이 있다.

 

 

* Pass By Reference

 

passed by reference 방식은 위와 같은 5가지의 Primitive type 에 적용되는 것은 아니고,

Object, Array, Function 에 적용되는 방식이다.

이 방식은 앞선 passed by value 처럼

새로운 메모리를 할당해서 값을 그대로 카피하는 방식으로 만들어서 따로 관리를 하는 것 이라면,

 

 

passed by reference 는 값을 가져오는게 아니라 "메모리 주소" 를 참조하는 변수를 생성해서 처리를 하는 것이다.

예를들면, 아래의 변수를 선언했다고 하면

arr.push(1);
cs

 

메모리 구조를 도식화 하면 아래와 같다고 가정할 수 있다.

 

passed by value 와 다른 점은 arr 라고 선언한 변수가 값을 가질때,

[] 에 대한 주소값을 갖는 다는 점이다.

[] 를 값으로 가지지 않는 다는 것이다.

 

만약 값을 추가하면 어떻게 될까?

arr.push(1);
cs

 

 

위와 같이 변수 arr 의 '값' 자체는 변하지 않는다. (variable arr is static)

다만 참조하고 있는 대상의 값만 변경 될 뿐이다.

JS engine 이 arr 이 가르키는 주소를 찾아가서 그 위치에 값을 저장하기 때문이다.

 

다른 주소를 참조하는 변수(여기선 arr)를 새 변수에 할당하면 어떻게 될까?

 

 

* Assigning By Reference

 

 예를들어 아래와 같이 코드를 쓰면 그 때의 메모리 구조는 어떻게 될까?

var arr = [1];
var arr2 = arr;
cs

 

위와 같이 arr2 를 arr 를 값으로 받는 변수를 선언하면

arr2 또한 [1] 의 위치를 가르키는 변수가 된다.

 

 

그리고 arr 과 arr2 둘 중 하나라도 값을 추가하게 되면,

둘다 같은 값을 출력하게 된다.

 

아래에는 arr.push(2); 를 한 결과 이다.

 

* Reassigning Reference

 

참조형의 변수에 또 다시 새로운 값을 할당하는 경우는 어떻게 될까?

아래의 코드 처럼 작성한다면

var obj = { first: "a" };
obj = { second: "b" };
cs

 

메모리 구조는 이렇게 바뀔 것이다.

obj 변수가 처음엔 메모리 주소값 100을 가르켰다가

재할당 되었으므로, obj 는 최종적으로 메모리 주소값 200을 가르키게 된다.

 

 

추가적으로 JS engine 은 Garbage Collection 기능을 가지고 있다.

위의 obj 예제는 GC(Garbage Collection) 에 의해서 

메모리주소 100에 해당하는 { first: "a" } 값은 더이상 접근 불가능한 값이 되며,

GC 가 이 값을 메모리에서 제거해준다.

 

* GC 에 대한 더 자세한 설명은 아래의 주소들을 참조하기 바란다

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management

 

Memory Management

Low-level languages like C, have manual memory management primitives such as malloc() and free(). In contrast, JavaScript automatically allocates memory when objects are created and frees it when they are not used anymore (garbage collection). This auto

developer.mozilla.org

https://javascript.info/garbage-collection

 

Garbage collection

 

javascript.info

 

 

보통 스크립트 언어(javascript, python 등) 를 배우는 경우, 

포인터에 대한 개념을 익히지 않기 때문에, 

call by value, call by reference 에 대한 개념을 모르는 경우가 많다

 

하지만 프로그램을 작성함에 있어서,

메모리 관리에 대한 이해를 하는 것은 아주 중요하다고 생각한다.

 

unmanaged language 의 대명사인

java 를 배울 때도, GC 에 대한 개념을 아는 것이 필요하다고 본다

728x90