
데이터 타입의 종류
1. 기본형 (원시형, primitive type)
number, string, boolean, null, undefined 등
2. 참조형
object, array, function, date, regexp 등
- 값이 담긴 주솟값들로 이루어진 묶음을 가리키는 주솟값을 복제
변수 선언과 데이터 할당
1. 변수 선언
var a;

2. 데이터 할당
var a;
a = abc;
var a = 'abc';

- 변수 영역에서 빈 공간 (@1003)을 확보
- 확보한 공간의 식별자를 a로 지정
- 데이터 영역의 빈 공간(@5004)에 문자열 'abc를 저장
- 변수 영역에서 a라는 식별자를 검색(@1003)
- 앞서 저장한 문자열의 주소(@5004)를 @1003의 공간에 대입
데이터가 저장 된 주소를 저장하는 이유
- 자유로운 데이터 변환과 효율적인 메모리 관리하기 위함
- 만약 값을 직접 저장한다면, 해당 공간을 넘어가는 데이터로 변환 할 경우 공간을 늘리는 작업 필요
- 해당 공간의 앞 뒤로 여유 공간이 있다면 문제 없겠지만, 여유 공간이 없을 경우 데이터를 전부 옮기는 연산 불가피 함
- 결국 변수와 데이터를 별도의 공간에 나누어 저장하는 것이 효율적으로 데이터 변환을 처리하는데 최적
기본형 데이터와 참조형 데이터
1. 불변값 (Immutable Value)
- 한번 만들어진 값은 변하지 않음
- 변수에 새로운 값을 할당하면 새로운 값을 만든 후 변수가 가리키는 데이터 주소를 변경
- 기본형 데이터는 모두 불변값
2. 가변값 (Mutable Value) - 참조형 데이터의 할당
var obj1 = {
a: 1,
b: bbb
}

- '객체의 변수(프로퍼티) 영역'이 별도로 존재
- 객체의 변수 영역에는 다른 데이터로 변경할 수 있기 때문에 가변값이다.
변수 복사 비교
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는 성립하지 않음
불변 객체 (Immutable Object)
불변 객체
- 값으로 전달받은 객체에 변경을 가하더라도 원본 객체는 변하지 않아야 하는 경우 불변 객체 사용
- 참조형 데이터의 '가변'은 데이터 자체가 아니라 내부 프로퍼티를 변경할 때 성립
불변 객체를 만드는 간단한 방법
- 내부 프로퍼티를 변경할 필요가 있을 때 마다 매번 새로운 객체를 만들어 재할당 하기로 규칙을 정함
- 자동으로 새로운 객체를 만드는 도구를 활용
- immutable.js, immer.js, immutability-helper 등의 라이브러리
- ES6의 spread operator, Object.assign 메서드 등
얕은 복사와 깊은 복사
- 얕은 복사(shallow copy)는 바로 아래 단계의 값만 복사
- 깊은 복사(deep copy)는 내부의 모든 값들을 하나하나 찾아서 전부 복사
- 얕은 복사로 하면 객체 안에 참조형 데이터가 있을 경우 불변 객체가 되지 않음
undefined와 null
undefined
- 사용자가 명시적으로 지정할 수 있지만 값이 존재하지 않을 때 자바스크립트 엔진이 자동으로 부여하는 경우도 있음
- 값을 대입하지 않은 변수, 즉 데이터 영역의 메모리 주소를 지정하지 않은 식별자에 접근할 때
- 객체 내부의 존재하지 않는 프로퍼티에 접근하려고 할 때
- return 문이 없거나 호출되지 않는 함수의 실행 결과
- 사용자가 명시적으로 부여한 undefined
- 비어있음을 의미하긴 하지만 하나의 값으로 동작하기 때문에 프로퍼티나 배열의 요소는 고유의 키값 (프로퍼티 이름) 이 실존하게 되고, 따라서 순회의 대상이 될 수 있음
- 자바스크립트 엔진이 반환하는 undefined
undefined와 null의 비교
const n = null;
console.log(typeof n);
console.log(n == undefined);
console.log(n == null);
console.log(n === undefined);
console.log(n === null);
- null의 타입이 object로 나오는 것은 JavaScript의 버그
- '없음'을 표현 하고자 할 때는 null을 사용
- 사용자가 표현한 '없음'(null) 인지 확인하고자 할 때는 === 연산자를 사용해서 비교