자바스크립트가 제공하는 7가지 데이터 타입은 크게 원시타입과 객체타입으로 구분 할 수 있다.
원시 타입 (원시 타입은 모두 “하나”의 정보(데이터)를 담고 있다.)
자바스크립트는 아래와와 같이 6가지의 원시형 데이터 타입이 있다.
숫자 타입 : ECMAScript 사양에 따르면 숫자 타입의 값은 배밀정도 64비트 부동소수점 형식을 따른다. 즉, 모든 수를 실수로 처리하며, 졍수만 표기하기 위한 데이터 타입이 별도로 존재하지 않는다.
문자열 타입 : 0개 이상의 16비트 유니코드 문자(UTF-16)의 집합으로 전 세계 대부분의 문자를 표현할 수 있다.
불리언 타입 : 논리적 참,거짓을 나타내는 true와 flase 뿐이다.
undefined 타입 : undefined 타입의 값은 undefined 가 유일하다. 변수를 선언한 이후 값을 할당하지 않은 변수를 참조하면 undefined 가 반환된다.
null 타입 : null 타입의 값은 null 이 유일하다. 프로그래밍 언어에서 null은 변수에 값이 없다는 것을 의도적으로 명시 할 때 사용한다. 함수가 유효한 값을 반환할 수 없는 경우 명시적으로 null을 반환하기도 한다.
심벌 타입 : 심벌은 ES6에서 추가된 7번째 타입으로, 변경 불가능한 원시 타입의 값이다. 심벌 값은 다른 값과 중복되지 않는 유일무이한 값이다. 따라서 주로 이름이 충돌할 위험이 없는 객체의 유일한 프로퍼티 키를 만들기 위해 사용한다. 심벌에 관한 내용은 따로 블로깅하여 추가 하도록 하겠다.
값의 할당
원시 타입은 메모리에 데이터 타입 실제 값이 저장된다, 이때 메모리에 고정된 양의 공간 확보하는데 이것을 "정적 메모리 할당" 이라고 한다.
불변성
아래의 이미지는 기본 값이 변경 불가능 하다는 것을 이해하는데 도움이 될것이다. 원시형 타입은 재할당 할 수 있지만 직접 변경할 수는 없다.
그렇다면 원시형 타입이 할당된 변수는 어떻게 재할당이 되는가?
모던 자바스크립트 Deep Dive: 자바스크립트의 기본 개념과 동작원리 (그림4-10 값의 재할당)
변수에 값을 재할당하면 score 의 값은 이전 80에서 재할당한 90 으로 변경된다. 처음 할당되어있던 80이 저장되어 있던 메모리 공간을 지우고 그 공간에 90을 새롭게 저장하는것이 아니라 위 이미지와 같이 새로운 메모리에 공간을 확보하고 그 공간에 90을 저장한다는 걸 알 수 있다.
<script>
let score = 80; // score에 80을 할당하였다.
let copy = score; // copy는 score를 참조한다.
console.log(score); // 80
console.log(copy); // 80
score = 100; // score에 100을 재할당 하였다.
console.log(score); // 100
console.log(copy); // copy의 값은?
</script>
위 스크립트와 같은 상황에서 copy의 값은 어떻게 되는가?
정답은 80이다.
모던 자바스크립트 Deep Dive: 자바스크립트의 기본 개념과 동작원리 (그림11-4 참조의 의한 전달)
위 그림과 같이 값에 의해 전달된 값은 다른 메모리 공간에 저장된 별개의 값이다. 두 변수의 원시 값은 서로 다른 메모리 공간에 저장된 별개의 값이 되어 어느 한쪽에서 재할당을 통해 값을 변경하더라도 서로 간섭할 수 없다.
즉, "값의 의한 전달"은 값은 전달하는 것이 아니라 메모리 주소를 전달한다. 단 전달된 메모리 주소를 통해 메모리 공간에 접근하면 값을 참조할 수 있다.
원시 타입 이외의 모든 값은 객체 타입이다.
객체 (object),함수(function),배열(arry) 등이 있다.
값의 할당
객체(참조) 타입은 메모리의 heap 영역에 주소가 저장된다. 이때 메모리에 동적으로 크기가 변하는데 이것을 "동적 메모리 할당" 이라고 한다.
heap?
위 이미지로 값이 저장되는 방식을 참고 할 수 있다.
변경 가능한값
객체(참조) 타입의 값은 변경 가능한 값이다. 원시 타입과 달리 객체(참조) 타입은 stack 에 heap의 주소를 참조하고 있기 때문에 이 참조값을 통해 객체에 접근할 수 있다.
객체(참조) 타입은 여러 개의 식별자가 하나의 객체를 공유 할 수있다.
<script>
let arr = [0,1,2,3]
let copy = arr; // 참조 값을 복사
console.log(arr); // [0,1,2,3]
console.log(copy); // [0,1,2,3]
arr.push(4);
console.log(arr); // [0,1,2,3,4]
console.log(copy); // copy의 값은??
</script>
위 스크립트와 같은 상황에서 copy의 값은 어떻게 되는가?
정답은 [0,1,2,3,4] 이다.
arr 와 copy 는 같은 heap의 주소를 참조하기 때문에 arr의 값이 변경되면 copy 도 따라 변경된다.
<script>
let arr = [0,1,2,3]
let copy = arr; // 참조 값을 복사
console.log(arr); // [0,1,2,3]
console.log(copy); // [0,1,2,3]
arr.push(4);
console.log(arr); // [0,1,2,3,4]
console.log(copy); // [0,1,2,3,4]
console.log(arr === copy); // true
</script>
같은 주소를 참조하기 때문에 동치연산자로 비교 해보았을때 true를 반환한다.