데이터 타입의 종류
기본형 타입(Primitive Type) | 참조형 타입(Reference Type) |
숫자(Number) |
객체(Object) |
기본형 타입(Primitive Type)
기본형 타입의 종류에는 숫자, 문자열, 불리언, null, undefined, symbol이 있습니다.
일반적으로 기본형은 '할당이나 연산시 데이터가 복제'된다고 알려져있습니다.
기본형 타입의 메모리 저장 방식
*메모리 할당영역, 주솟값에 대한것은 이해를 돕기위한 개략적인 이미지들이 등장합니다.
메모리 할당 시 두 영역을 사용한다고 생각하면 쉽습니다.
-
식별자가 할당되는 변수 영역
-
데이터 값이 담기는 데이터 영역
변수 영역에는 식별자와 데이터 영역의 주솟값으로 이루어져있습니다.
데이터 영역에는 데이터가 담겨있습니다.
예시1) 변수 선언
var name = '홍길동';
변수 영역(1002)에 식별자(변수명)를 name으로 할당합니다.
데이터 영역(5000)에 문자열 '홍길동' 데이터를 할당합니다.
식별자 name의 변수 영역에 데이터 영역의 주솟값을 값에 연결해줍니다.
사용자가 식별자 name을 호출했을때,
해당 변수 영역 값에 연결된 주솟값(5000)에 담긴 데이터가 반환됩니다.
예시2) 데이터 재할당
var name = '홍길동';
name = '고길동';
새로운 데이터이므로 비어있는 데이터 영역(5001)에 문자열 '고길동'을 할당합니다.
식별자 name에 변수 영역에 해당하는 데이터 영역의 주솟값(@5000 -> @5001)으로 변경해줍니다.
예시3) 변수에 변수를 대입
var name = '홍길동';
var name2 = name;
비어있는 변수 영역(1003)에 식별자 name2를 할당하고
name2의 데이터 주소에 name의 주솟값(5000)을 가져와 할당합니다.
name2의 데이터가 변경되는 부분을 이어서보겠습니다.
var name = '홍길동';
var name2 = name;
name2 = '고길동';
새로운 문자열 '고길동'을 비어있는 데이터 영역(5001)에 할당하고 식별자 name2의 주솟값을 변경해줍니다.
?????!
여기서 궁금한 점이 등장합니다.
데이터 영역에 문자열 '홍길동'을 넣었다가 문자열 '고길동'으로 변경했을때,
해당 영역의 데이터를 수정하지 않고 오ㅐ? 새로운 메모리 영역을 사용하는가?
이것을 이해하기위해서는 불변성을 이해해야합니다.
불변성(Immutability)
단순히 정의만을 말하자면 '변하지 않는 성질'이라고 할 수 있습니다.
하지만 불변성이 해당하는 부분이 어디인지를 확실히 이해해야합니다.
불변성은 변수와 상수의 개념으로 말하는 것이 아닙니다.
변수와 상수는 변수 영역 메모리에 데이터 할당 후 재할당이 되는지에 대한 여부로 구분되는 것이며
불변성은 데이터 영역의 메모리에 대한 것 입니다.
예시로 간단히 보겠습니다.
var name = '홍길동';
name = '고길동';
변수
식별자 name의 변수 영역에 값이 문자열 '홍길동'에서 '고길동'으로 재할당이 되었으므로
해당 데이터 영역 주솟값으로 변경해줍니다.
(5000 -> 5001)
변수는 이처럼 데이터 영역의 주솟값 재할당이 가능합니다. (재할당)
상수
상수는 데이터 주솟값 재할당이 안되므로
식별자 name의 변수 영역에 데이터 값 변경이 불가능합니다.
불변성
불변성은 식별자 변수 영역에 해당하는 데이터 값의 재할당이 기준이아니고
데이터 영역의 데이터가 변경이 가능한지에 대한 여부입니다.
즉 문자열 '홍길동'에서 '고길동'으로 변경되었을때, 데이터 영역의 데이터는 변경할 수 없습니다.
불변성에 의해 비어있는 데이터 영역에 새로 문자열 '고길동'을 할당 한 후
식별자 name의 데이터 주솟값이 재할당됩니다.
위의 예시에서 알 수 있듯,
데이터 영역의 데이터는 한번 생성되었을 경우 수정이 안되며(불변성)
새로운 데이터일 경우 비어있는 데이터 영역에 새로 할당됩니다.
그리고 새로 할당된 데이터 영역의 주솟값을 변수 영역의 데이터 주솟값으로 재할당하는 것입니다.
즉, 데이터 영역의 변경이란 새로 만드는 동작에서만 이루어집니다.
불변성은 왜 필요한거지?라는 의문이 또 한번 머리에 스쳐지나갈 수 있습니다.
간단하게, 메모리 저장에 대한 이야기를 해보겠습니다.
메모리에 데이터를 저장하기 위해서는 메모리 공간을 선행으로 확보해야합니다.
불변성이 없다고 생각했을때,
처음 저장한 데이터의 크기보다 더 큰 데이터를 '재할당' 해야한다면 어떤일이 생길까요?
데이터 공간을 재확보해야하는 일이 생깁니다.
그리고 이 재확보작업을 하게되면 뒤에 저장된 메모리들의 공간이 뒤로 밀리는 현상이 생기고
이 현상으로 인해 각각의 주솟값들을 식별자에 다시 연결해야하는 작업이 발생할 수 있습니다.
위와 같은 이유로 불변성은 효율적으로 데이터를 저장하기 위해 생겼습니다.
참조형 타입(Reference Type)
참조형 타입의 종류는 객체, 배열, 함수, 날짜, 정규표현식, Map, WeakMap, Set, WeakSet이 있다.
일반적으로 참조형은 '참조된다'고 알려져있습니다.
참조형 타입의 메모리 저장 방식
*메모리 할당영역, 주솟값에 대한것은 이해를 돕기위한 개략적인 이미지들이 등장합니다.
예시1) 변수 선언
var person = {
name : '홍길동',
age : 123
};
기본형타입과 마찬가지로 변수 영역, 데이터 영역이 존재합니다.
식별자 person 변수 영역에 데이터 영역 주솟값을 연결해줍니다.
하지만 참조형타입은 영역이 하나 더 존재합니다.
'객체의 변수(프로퍼티) 영역'입니다.
데이터 영역 주솟값에 데이터가 바로 할당되는 것이 아니라 객체의 프로퍼티 영역의 주솟 값(7000~7001)이 연결됩니다.
그리고 해당 객체의 프로퍼티 영역에 데이터 영역의 주솟값을 연결해줍니다.(name-5002 / age-5003)
위에서 데이터 영역은 불변하다고 말했던 것처럼 참조형 데이터도 데이터 영역은 불변하다고 할 수 있습니다.
하지만
기본형 타입은 불변성을 띄고 참조형 타입은 불변하지 않다(가변성)고들 말한다고 하는데,
그 이유를 짚어보겠습니다.
예시2) 참조형타입은 가변성을 띄는가
var person = {
name : '홍길동',
age : 123
};
person.name = '고길동';
식별자 person의 변수 영역의 값과 데이터 영역(5000)의 값이 변경되지 않았습니다.
하지만 객체의 프로퍼티 영역의 데이터 주솟값이 변경된 것이 확인 되는데,
이같은 부분을 보고 가변성을 띈다고 하는 것입니다.
간단히 말해..
person의 데이터 영역은 불변성을 띄지만,
person의 객체의 프로퍼티 영역은 가변성을 띈다고 할 수 있습니다.
예시3) 참조형 타입이 참조인이유
var person = {
name : '홍길동'
};
var person2 = person;
식별자 person의 값을 person2에 대입하게되는 경우에 위와 같이 같은 데이터 영역의 주솟값을 가지게 됩니다.
이 부분은 기본형 타입과 참조형 타입 둘 다 동일합니다.
두 타입의 차이는 데이터 영역, 객체의 프로퍼티 영역에서 확인할 수 있습니다.
아래와 같이 식별자 person2의 name 프로퍼티의 데이터를 수정하게 될 경우 생기는 변화에 대해 확인해보겠습니다.
var person = {
name : '홍길동'
};
var person2 = person;
person2.name = '고길동';
변수 영역의 주솟값이나 데이터 영역의 주솟값은 변경되지 않습니다.
name 프로퍼티만 변경된 것이므로 해당 객체의 프로퍼티 영역에서 데이터 주솟값을 변경합니다.
즉, 5002에서 5003으로 변경합니다.
이때 해당 객체의 프로퍼티 영역의 주솟값만 변경하므로 변수 영역, 데이터 영역을 참조하고 똑같이 참조하고 있던
person역시 영향을 받습니다.
var person = {
name : '홍길동'
};
var person2 = person;
person2.name = '고길동';
console.log(person.name); // '고길동'
예시4) 객체끼리 참조하지 못하게 하려면
var person = {
name : '홍길동',
age : 123
};
var person2 = person;
person2 = {
name : '홍길동'
age : 300
};
식별자 person의 객체를 person2에 대입하고나서 새로운 객체로 데이터 자체를 변경해버리면 불변성을 유지할 수 있습니다.
객체 자체를 재 선언해버리면 새로운 객체의 프로퍼티 영역이 생기게 되고 이때 연결된 기존 객체 프로퍼티 영역의 주솟값이 변경되어 버리므로 서로 참조하지 않습니다.
(객체의 프로퍼티영역이 각각 생김)
즉, 참조형 데이터가 가변성을 띈다라고 말할수 있는 부분은
참조형데이터 자체를 변경할 때가 아닌 내부 프로퍼티를 변경하는경우에만 성립됩니다.
(참조되는 객체의 불변성을 지키기위해 복사하여 사용하기도합니다.)
하지만 어떠한 데이터 타입이든 변수에 할당하기 위해서는 데이터를 직접 할당하는 것이 아닌 데이터 영역의 주솟값을 복사하기 때문에 자바스크립트의 모든 데이터 타입은 참조형 데이터일 수 밖에 없습니다.
기본형도 결국 주솟값을 참조하는 형태입니다.
다만 기본형은 주솟값을 데이터 영역에서 한번 만 복사해오고 참조형은 객체의 프로퍼티 영역 한단계를 더 거치는 차이가 있습니다.
출처
-
https://developer.mozilla.org/ko/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript
-
코어 자바스크립트:핵심 개념과 동작 원리로 이해하는 자바스크립트 프로그래밍,(저자 정재남)
'~2022 > FE-개발 개념' 카테고리의 다른 글
클로저(Closure) (0) | 2021.01.01 |
---|---|
this (0) | 2020.12.09 |
실행 컨텍스트(Execution context) (0) | 2020.12.09 |
undefined와 null (0) | 2020.12.09 |
변수(Variable)와 식별자(Identifier) (1) | 2020.12.08 |
Chrome 80 SameSite 속성 동작 변경 (0) | 2020.06.26 |
[jQuery기초] 버전별 특성 (0) | 2020.06.18 |
[jQuery기초] jQuery란? (0) | 2020.06.17 |