본문 바로가기

Javascript

자바스크립트 - Primitive type vs Reference type

728x90

들어가기에 앞서

let age = 20;
let oldAge = age;

age = 21;

console.log(age);
console.log(oldAge);

위의 결과는 당연히 21 / 20 이 차례대로 출력될 것입니다.

const overaction = {
    first: 'over',
    food: 'apple',
};

const friend = overaction;

friend.food = 'banana';

console.log(friend);
console.log(overaction);

그렇다면 위의 코드처럼 객체를 복사했을 경우 결과는 어떻게 될까요?

friend 객체의 food 값만 바꾸길 원했는데 overaction 객체의 food 값도 바뀌었습니다.

왜 이런일이 발생하는 걸까요?

 

 

Primitive vs Object

Primitive에는 Number, String, Boolean, Undefined, Null, Symbol, BigInt 이렇게 7가지 종류가 있고

이들은 Primitive type 입니다.

 

이 외의 것들은 Object 이며 Array, Function 등이 있으며

이들은 Reference type 입니다. 

 

앞선 포스팅에서 자바스크립트 엔진에는 call stack과 heap 이 존재한다고 했었는데,

call stack은 함수들이 실행되는 곳이며 heap은 Object들이 저장되는 공간입니다.

 

즉 primitive types들은 call stack에 저장되며 (더 정확히 말하면 실행컨텍스트)

reference types들이 heap에 저장되는 것입니다.

 

 

 

Primitive type의 경우

let age = 30;
let oldAge = age;

age = 31;

console.log(age);
console.log(oldAge);

먼저 위의 예제에서 첫 줄을 보겠습니다.

기본적으로 변수를 선언하면 Identifier , Address, Value가 생성되며

age라는 변수는 value를 직접 갖는것이 아니라 Address 주소값을 참조하게 됩니다.

두 번째 줄에서 oldAge 역시 같은 Address를 참조하게 됩니다.

세 번째 줄에서 age값을 31로 바꿨을 때, Address의 value 값이 바뀌는 것이 아니냐고 생각할 수 있지만,

특정 메모리 Address의 Value 값은 불변이기 때문에 새로운 주소값이 생성되게 됩니다.

앞의 모든 과정은 Call stack에서 일어나는 일입니다.

 

 

Reference type의 경우

const overaction = {
    first: 'over',
    food: 'apple',
};

const friend = overaction;
friend.food = 'banana';

console.log(friend);
console.log(overaction);

 

위 코드에서 overaction 객체를 생성했을 시 일어나는 일은

overaction 이라는 객체가 처음 만들어질 경우 Heap에 저장됩니다.

다만 call stack 에서 value를 같은 값으로 가져서 Heap의 address를 참조하게 됩니다.

 

객체가 stack에 저장되기에는 크기가 너무 클 수 있기 때문에, 공간이 거의 무제한인 heap에 저장하고

대신 heap에 저장되는 위치를 참조해서 언제든지 찾을 수 있도록 하는 방식입니다.

 

객체를 복사하더라도 힙에 새로운 객체를 만들지 않으며, call stack에 새로운 변수를 만들고 같은 메모리 주소를

참조합니다.

이제 객체를 복사해도 같은 D30F라는 값을 가지며, 따라서 참조하는 위치도 같기 때문에

friend의 food 값을 banana로 변경했을 시 동일하게 적용됩니다.

728x90