자바스크립트의 타입은 크게 두 가지로 구분한다. 오늘은 참조형과 자료형의 차이에 대해서 간략히 정리해보았다.
- 원시자료형 - Number, String, Boolean, null, undefined, Symbol, BigInt
- 참조자료형 - 객체, 배열
간단한 타입에대한 내용은 이전 글을 참조
참조자료형은 왜 생겼을까?
참조 자료형은 대량의 데이터를 사용하고 싶기때문에 등장했다.
기존의 자료형은 하나의 변수가 하나의 값만 가지고 있다.
let apple = "사과";
그러나 사과 한개가 아니라 여러가지 과일을 표현하고 싶을 때, 위처럼 하나의 변수에 하나의 값만 넣어서 사용할 수 있는 구조는 매우 불편하다.
let fruit = "사과, 바나나, 복숭아, ..., 메론"
// 사용하기 위해서는 ,를 구분해서 전부 잘라줘야한다.
따라서 대량의 데이터를 더 쉽게 사용하기 위해서 참조자료형이 등장했다.
값을 저장하는 방법
원시형과 참조형의 차이 알아보기 전에, 자바스크립트가 어떻게 값을 저장하는지 간략하게 설명하겠다.
변수 선언과 값의 할당
자바스크립트는 변수를 선언을 두가지 단계에 거쳐 실행한다.
- 선언 단계 - 변수 이름을 등록하는 단계
- 초기화 단계 - 값을 저장하기 위한 메모리 공간을 확보하고 초기화하는 단계
let a = 10;
위와 코드는 a라는 변수 이름을 등록한 후에 a에 10을 할당하게 된다.
- 메모리 공간에 a라는 이름을 가진 공간을 할당하고
- 후에 10이라는 값의 메모리 공간을 할당한 후에
- 메모리 공간 a가 10이라는 값의 공간을 가리키도록 한다.
원시형과 참조형의 데이터 보관 방법
원시자료형의 데이터 저장은 위에서 설명한 것처럼 작동한다.
그러면 참조형은 어떻게 값을 저장할까?
원시형과 마찬가지로 똑같다. 그럼 차이가 없는 것일까? 그건 아니다.
참조자료형의 값의 메모리 공간(여기선 0x0001444)은 값이 수정될 수 있다.
즉, {name:"Kim", age:23}의 값을 수정하더라도 변수 person이 가리키는 메모리 주소값은 변하지 않는 다는 것이다.
그러나 원시형타입은 다르다. 원시값은 불변이다.
여기서 중요한 부분은 값이 불변이라는 뜻이다. 즉, 위 객체의 값은 변할 수 있지만 원시형 값은 변할 수없다.
이미지1의 값 60이 존재하는 메모리 공간 0x00001444의 값을 변경할 수 없다.
그렇기때문에 만약 값을 10으로 변경하고 싶은 경우 메모리 공간에 새로 10이라는 값을 생성하고 변수 a가 메모리공간에 가지고 있는 주소를 새로운 값인 10이 들어있는 주소로 변경하는 것이다.
참조형인 경우에만 메모리 주소를 저장하는 게 아니였나요?
아마 위 내용을 보면
"참조형인 경우에만 메모리 공간에 메모리주소를 저장하고
원시형인 경우에는 메모리 공간에 값 자체를 저장하는게 아닌가?
하고 의문을 가질 수 있을 것이다.
그러나 엄밀히 말하면 변수는 그 값이 들어있는 메모리 주소를 가지고 있고 값이 아니라 식별자이다.
값 자체는 메모리 공간에 따로 존재하는 것이다.
let a = 10;
let b = a; // 변수는 주소를 가지고 있다는데.. 그럼 둘도 같은 메모리 주소일까??
b = 100;
console.log(a); // 10
console.log(b); // 100
그럼 또 위와같은 코드에 의문이 생긴다.
변수가 가지고 있는 값이 자료형과 상관없이 사실상 메모리 주소라면 원시형 변수를
다른 변수에 할당하면 둘은 같은 메모리 주소를 공유하는 것일까?
그렇다면 b에 a를 할당하고 b를 변경했을 때, 참조형처럼 a값도 변경되는 것일까?
물론 아니라는 걸 모두 알고 있다.
원시형 타입의 변수를 할당하는 경우 해당 값을 메모리공간에 새로 만들어 낸다.
그리고 그 값의 메모리 주소를 변수 b가 가지게 된다.
따라서 두 값은 다른 메모리 공간에 저장된 별개의 값이기 때문에 서로 영향을 주지 못한다.
물론 실제 동작과정은 조금 다를 수 있다.
변수에 변수를 할당한 경우,둘이 같은 메모리 공간을 가리키다가
한쪽 변수에 재할당이 일어난 경우 메모리 공간을 따로 확보하는 식으로도 작동한다.
따라서 b에 새로운 값 100을 넣더라도 값 100을 따로 메모리 공간에 선언한 후 b가 가리키는 메모리 주소를 변경하는 것이기때문에 a와 b는 서로 관계가 없다.
그래서 원시형과 참조형의 차이점은?
- 원시형은 값이 불변이기때문에 새로 값을 할당하는 경우 새로운 메모리 공간을 만들어내 새로운 주소를 변수에 저장한다.
- 그러나 참조형은 값이 불변이 아니기때문에 값을 수정하더라도 변수가 가지고 있는 메모리 주소값은 변하지 않는다.
- 그렇기때문에 참조형 변수를 다른 변수에 할당하면 같은 메모리 주소를 가지기때문에 어느 한쪽값을 변경하면 서로가 영향을 주는 것이다.
좀 더 자세히 정리를 하자면 자바스크립트 엔진이 메모리를 어떻게 관리하는지 공부해야할 것 같다. 이번주 주말에는 heap과 같은 메모리구조에 대해 공부할 예정..
'공부 > 자바스크립트' 카테고리의 다른 글
[js] 객체지향 프로그래밍 (0) | 2022.11.18 |
---|---|
[js]자바스크립트 클래스 (0) | 2022.11.18 |
[js] 객체 구조 분해 할당과 얕은 복사 방식들 (0) | 2022.11.09 |
[js] "1" + "1" = "11"인 이유 (0) | 2022.11.05 |
클래스 기반 객체 지향 언어 vs 프로토타입 기반 객체 지향 언어 (2) | 2022.10.30 |
댓글