일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- SQL
- svn
- Java
- @RequestBody
- MySQL
- Mac
- class-transformer
- 인텔리제이
- javascript error
- Spring
- DART
- db
- 프로그래머스
- 프로젝트 여러 개
- JavaScript
- InteliJ
- flutter mac 설치
- oracle
- 코어자바스크립트
- Aspect
- maven
- REST
- ojdbc6
- Stream
- eqauls-hashcode
- node.js
- 봤어요처리
- tecoble
- datagrip 한글깨짐
- TypeScript
- Today
- Total
개발자가 되고 싶은 개발자
[JavaScript] 데이터 타입- 참조형 본문
(코어 자바스크립트(정재남 저- 위키북스)를 참조하여 작성했습니다.)
자바스크립트의 데이터 타입에는 기본형(원시형, Primary Type)과 참조형(Reference Type)이 있습니다.
기본형 데이터와 비교해보며 참조형에 대해 알아보도록 하겠습니다.
객체(Object)
자바스크립트의 참조형은 객체이고, Array, Function, RegExp, Date, Map, Set 등이 객체의 하위분류로 속해있습니다.
기본형의 데이터 할당
먼저, 기본형과 참조형의 구분은 데이터를 저장하는 방식에 따라 구분됩니다.
기본형의 데이터 할당부터 알아보도록 하겠습니다.
- 기본형은 값을 가리키는 주솟값을 바로 복제합니다.
- 참조형은 값들을 가리키고 있는 주솟값들의 묶음을 가리키는 주솟값을 복제합니다.
- 기본형은 값을 할당할때 혹은 연산할때 주소를 복제한다고 하고,
참조형은 참조한다고 알려져 있지만, 사실 둘 다 복제가 이뤄집니다.
예를 들어 a라는 변수를 선언하고 a에 10이라는 숫자 값을 할당해보겠습니다.
(책에서는 데이터의 성질에 따라 메모리 공간을 변수 영역/데이터 영역으로 나누어 설명합니다.)
- 변수 영역의 메모리에서 빈 공간을 할당하고, 해당 주소(1001)의 식별자(변수명)를 a라고 저장합니다.
- 데이터 영역에서 값을 검색한 후 10이란 값이 없으니, 10을 저장하고 해당 주소(5001)를 a의 값으로 저장합니다.
- 즉, 식별자의 값에 바로 10을 저장하는 것이 아닙니다.
let a = 10;
// 변수영역
------------------
주소 1001
------------------
데이터 이름: a
값: @5001
------------------
// 데이터 영역
------------------
주소 5001
------------------
데이터 값: 10
------------------
기본형은 이처럼 값을 가리키는 주소를 바로 복제합니다.
기본형은 불변성을 띈다고 알려져 있습니다.
불변하다는 것은 a에 10을 할당하고 다시 20을 할당하지 못한다는 것이 아니라 값 10에 대한 메모리 영역이 변하지 않는다는 것을 의미합니다.
(상수는 a에 10을 할당하고 20을 재할당하지 못합니다.
상수는 데이터 영역의 메모리가 아닌, 변수 영역의 값을 재할당하지 못합니다.)
즉, 변경 불가능의 대상은 변수 영역이 아닌 데이터 영역을 말합니다.
1001에 할당되는 값(변수영역)은 얼마든지 변할 수 있지만 데이터 영역의 값은 가비지 컬렉팅을 당하지 않는 이상 절대 변하지 않습니다.
(변수영역은 얼마든지 변할 수 있다고 한 점을 기억하고 아래에서 참조형의 설명을 보겠습니다.)
만약 변수 a의 값을 20으로 재할당한다면, 새로운 메모리 영역(ex. 5002)에 20을 새로 만들어 그 주소로 변경해줍니다.
예를 들어 5000개의 변수를 선언하고 전부 10으로 초기화 해준다면, @5001의 주소만 넣어주면 되기 때문에 새로운 값을 메모리에 할당하는 5000번의 연산을 절약할 수 있습니다.
참조형의 데이터 할당
참조형은 값들을 가리키는 주솟값들의 묶음을 가리키는 주솟값을 복제한다고 하였습니다.
기본형처럼 데이터 영역의 주솟값을 바로 저장하는 것이 아니라,
객체의 속성들을 저장하기 위한 별도의 변수영역이 존재합니다.
참조형은 기본적으로 가변 하다고 알려져 있습니다.
위에서 기본형을 설명하며 데이터 영역의 값은 절대 변하지 않는다고 했는데,
참조형은 변수영역을 별도로 갖기 때문에 이 값들은 얼마든지 변경할 수 있습니다.
그래서 이러한 특징을 보고 참조형은 가변하다고 알려져 있는 것입니다.
이 별도의 변수영역에 저장한 속성들의 주소의 묶음을 데이터 영역에 저장하는 것을 저장합니다.
let obj = {
a = 1,
b = 'test'
}
// 변수영역
------------------
주소 1001
------------------
데이터 이름: obj
값: @5001
------------------
// 데이터 영역
------------------------------------
주소 5001 5002 5003
------------------------------------
데이터 @7001~? 1 'test'
------------------------------------
// @5001의 변수 영역
------------------------------------
주소 7001 7002
------------------------------------
데이터 이름: a 이름: b
값: @5002 값: @5003
------------------------------------
참조형도 마찬가지로, 데이터 영역의 값은 변하지 않습니다.
예를 들어 obj.1의 값을 2로 변경하는 연산을 수행해보겠습니다.
데이터 영역에 2가 없으므로, 5004에 2를 할당하고, 7001의 값을 해당 주솟값(@5004)으로 변경해줍니다.
...
------------------
주소 1001
------------------
데이터 이름: obj
값: @5001
------------------
// 데이터 영역
------------------------------------
주소 5001 5002 5003 5004
------------------------------------
데이터 @7001~? 1 'test' 2
------------------------------------
// @5001의 변수 영역
------------------------------------
주소 7001 7002
------------------------------------
데이터 이름: a 이름: b
값: @5004 값: @5003
------------------------------------
@7001의 값은 변경됐지만, 해당 영역은 변수 영역이고, 데이터 영역인 @5001의 값은 변하지 않았습니다.
즉, 새로운 객체가 만들어지는 것이 아닌 객체 내부의 값만 변경된 것입니다.
참조형 데이터의 복사
기본형 데이터와 저장하는 방식에 차이가 있기 때문에 복사하는 과정에서도 차이가 크게 발생합니다.
메모리에서 변수 영역은 얼마든지 변경이 가능하다고 했습니다.
let a = 1; //1은 데이터 영역의 5004번에 저장돼있음.
let b = a;
a = 2;
console.log(a); //2
console.log(b); //1
위의 예제의 선언부에서는 둘 다 @5004번을 가리키고, a=2 연산을 수행했을 때는 a의 값만 2로 변경되어 의도했던데로 각각 2,1의 값을 반환합니다.
참조형의 복사하는 과정을 보겠습니다.
let a = {
name = 'test'
}
let b = a;
a.name = 'changed'
console.log(a.name); //changed
console.log(b.name); //changed
참조형의 메모리 중 데이터 영역의 값이 가리키고 있는 주소는 속성들의 주솟값 묶음을 가리키고 있습니다.
그래서 a, b는 결국 같은 속성 묶음을 가리키고 있는 것이고 a를 변경한 것이지만 b의 속성에서 접근했을 때도 변경된 결과가 반환이 됩니다.
이런 문제들 때문에 불변객체가 필요하고, 객체의 속성을 복사해서 새로운 객체를 반환하는 등의 방법으로 참조형이 가변하다는 특성으로부터 발생되는 문제를 해결 할 수 있습니다.
'Dev > JavaScript & TypeScript' 카테고리의 다른 글
[TypeScript] 이펙티브 타입스크립트-(Part.2) 2장 타입스크립트의 타입 시스템 (0) | 2022.05.03 |
---|---|
[JavaScript] this (0) | 2022.05.03 |
[JavaScript] 실행 컨텍스트 (0) | 2022.04.25 |
[TypeScript] 이펙티브 타입스크립트-(Part.1) 2장 타입스크립트의 타입 시스템 (0) | 2022.04.25 |
[TypeScript] 이펙티브 타입스크립트- 1장 타입스크립트 알아보기 (0) | 2022.04.18 |