데이터 타입
데이터 타입의 종류
- 기본형 - number, string, boolean, null, undefined, symbol 등
- 참조형 - object, array, function, date, RegExp, Map,Set등
기본형
기본형은 값이 담긴 주솟값을 바로 할당
참조형
참조형은 값이 담긴 주솟값으로 이루어진 묶음을 가르키는 주솟값을 할당
변수 선언 데이터 할당
var a = 1;
위와 같은 변수 선언 및 데이터 할당은 아래와 같이 진행된다.
바로 변수 영역에 값을 직접 대입하지 않는 이유
- 데이터 변환을 자유롭게 한다.
- 메모리를 더욱 효율적을 관리
기본형 데이터와 참조형 데이터
불변 값
- 변수(variable)과 상수(constant)를 구분하는 성질은 '변경 가능성'
- 불변값은 상수가 아님.
- 변수 vs 상수 구분 짓는 변경 가능성의 대상은 변수 영역의 메모리
- 불변성 여부를 구분할 때의 변경 가능성은 데이터 영역의 메모리
- 기본형 데이터(숫자, 문자열, boolean, null, undefined, Symbol) 모두 불변값
var a = 'abc'
a = a + 'def'
var b = 5;
var c = 5;
b = 7;
- 이처럼 문자열 값은 한번 만들면 변경할 수 없다.
- 변경은 오로지 새로 만드는 동작을 통해서만 이뤄진다.
- 한번 만들어진 값은 가비지 컬렉팅을 하지 않은 한 영원히 변하지 않는다.
가변값
- 참조형 데이터의 기본적인 성질은 가변값이 경우가 많다.
- 설정에 따라 변경 불가하게 활용할 수도 있음
var obj1 = {
a: 1,
b: 'bbb'
}
- 변수 obj1의 메모리(@1002) 할당
- 데이터({a:1, b: 'bbb'})를 저장하기 위한 메모리(@5001) 할당
- 해당 메모리에 데이터를 저장하려고 보니 여러 프로퍼티로 이뤄진 데이터 인 것을 알게 됨.
- 프로퍼티를 별도로 저장하기 위해 객체 @5001의 메모리 영역을 별도로 만들고, 해당 영역 주소(@7103 ~ ?)를 @5001 의 값에 저장
- 프로퍼티 a의 메모리(@7103)에 숫자 1이 저장 된 메모리 주소(@5003)를 저장
- 프로퍼티 b의 메모리(@7104)에 문자열 'bbb'가 저장 된 메모리 주소(@5004)를 저장
메모리 변화
let obj1 = {
a: 1,
b: 'bbb'
};
obj1.a = 2;
- obj1의 저장 된 메모리(@5001)의 값에는 변화가 없음
- obj1의 프로퍼티 a가 저장 된 주소(@7103) 값을 숫자 2가 저장 된 메모리 주소(@5005)로 교체
중첩된 참조형 데이터(객체)의 프로퍼티 할당
let obj = {
x: 3,
arr: [ 3, 4, 5]
};
- obj를 위한 메모리(@1002) 할당
- obj의 데이터를 저장하기 위한 메모리(@5001) 할당하고 obj 메모리(@1002) 값에 저장
- 데이터가 다중 프로퍼티로 이뤄진 것을 확인하여 @5001의 변수 영역을 할당(@7103 ~ ?)하고 - - obj의 데이터영역 메모리(@5001) 저장
- 프로퍼티 x를 위한 메모리(@7103)에 숫자 3이 저장 된 메모리 주소(@5002)를 저장
- 프로퍼티 arr를 위한 메모리(@7104)에 저장 할 데이터가 다중 프로퍼티로 이뤄진 것을 확인하여 해당 객체를 위한 변수 영역을 할당(@8104 ~ ?)하고 비어있는 데이터 영역 메모리(@5003)에 저장
- 프로퍼티 arr의 변수 영역이 저장 된 메모리(@5003)의 주소를 프로퍼티 arr를 위한 메모리(@7104) 값에 저장
- 프로퍼티 arr내부의 프로퍼티 중 0번째에 들어갈 데이터 숫자 3은 이미 @5002 번지에 있어서 해당 메모리 주소를 @8104에 저장
- 나머지 1, 2번째 프로퍼티의 값은 새롭게 할당하여 각각 @5004, @5005 번지에 저장하고 해당 주소를 @8105, @8106 값에 저장
중첩 된 참조형 데이터(객체)의 프로퍼티 재할당
let obj = {
x: 3,
arr: [ 3, 4, 5]
};
obj.arr = 'str';
- obj.arr 프로퍼티의 메모리(@7104) 값은 문자열 'str'이 저장 된 메모리 주소(@5006)으로 교체
- 객체 [3, 4, 5] 를 위해 사용되었던 메모리 (@5003, @8104 ~)는 GC(가비지 컬렉터)의 수거 대상이 됨
변수 복사 후 프로퍼티 변경
let a = 10;
let b = a;
let obj1 = { c: 10, d: 'ddd' };
let obj2 = obj1;
b = 15;
obj2.c = 20;
- 복사하고 하면 프로퍼티 변경 시 원본에 영향을 안 미칠 것을 대기 함
- a, b 값이 다르고, obj1, obj2가 다른 값을 가지고 있어야 함
- 하지만 실제로 그렇지 않음
- 기본형 데이터 변수인 a, b의 경우에는 b의 메모리(@1002) 값이 숫자 15가 저장 된 메모리 주소(@5004)로 변경 됨. 그래서 a !== b 성립
- 참조형 데이터 변수인 obj1, obj2의 경우에는 obj2의 메모리(@1004)에는 전혀 변화가 없고, 프로퍼티 c가 저장 된 메모리(@7103)의 값이 숫자 20이 저장 된 메모리 주소(@5005)로 변경 됨.
- 그런데 obj1과 obj2의 메모리(@1003, @1004) 값에는 전혀 변화가 없기 때문에 obj1 !== obj2는 성립하지 않음
변수 복사 후 객체 자체를 변경
let a = 10;
let b = a;
let obj1 = { c: 10, d: 'ddd' };
let obj2 = obj1;
b = 15;
obj2 = { c: 20, d: 'ddd' };
- 새로운 객체를 위한 변수 영역(@8204 ~ ?)이 새롭게 할당
- 해당 변수 영역을 저장 할 데이터 영역(@5006)도 새롭게 할당
- 그 값을 obj2 메모리(@1004) 값에 저장
- 서로 바라보는 객체 자체가 다르기 때문에 obj1 !== obj2 성립
불변 객체 (immutable object)
- 불변 객체는 React.js, Vue.js, Angular.js 뿐만 아니라 함수형 프로그램, 디자인 패턴에서도 등장하는 중요한 기초 개념
- 참조형 데이터의 '가변'은 데이터 자체가 아니라 내부 프로퍼티를 변경할 때 성립
불변 객체 만든 법
- 내부 프로퍼티를 변경할 필요가 있을 때 마다 매번 새로운 객체를 만들어 재할당 하기로 규칙을 정함
- 자동으로 새로운 객체를 만드는 도구를 활용
->immutable.js, immer.js, immutability-helper 등의 라이브러리
ES6의 spread operator, Object.assign 메서드 등
->immutable.js, immer.js, immutability-helper 등의 라이브러리
ES6의 spread operator, Object.assign 메서드 등
참조 - https://velog.io/@modolee/core-javascript-01