자바스크립트(ES6)는 7개의 데이터 타입을 제공하며 크게 원시타입과 객체타입으로 구분되어 있다.
원시값(primitive, 또는 원시값)이란 객체가 아니면서 메서드도 가지지 않는 데이터이다.
console.log(typeof null); // "object"
var x; // 값을 할당하지 않고 변수 선언
console.log("x's value is", x)
// "x's value is undefined"
Number 타입 : 부동소수점 숫자, +Infinity, -Infinity, NaN("Not a Number")등의 값을 가진다.
BigInt 타입 : 임의 정밀도로 정수를 나타낼 수 있는 숫자 원시 값이다. BigInt를 Number의 안전 한계를 넘어서는 큰 정수도 안전하게 저장하고 연산할 수 있습니다.
String 타입 : 텍스트 데이터를 나타낼 때 사용한다. String은 16비트 부호 없는 정수 값 "요소"로 구성된 집합으로, 각각의 요소가 String의 한 자리를 차지한다.
( String의 길이는 그 안의 요소 수와 같다. )
Symbol 타입 : 값으로 익명의 객체 속성(object property)을 만들 수 있는 특성을 가졌다. 이 데이터 형식은 클래스나 객체 형식의 내부에서만 접근할 수 있도록 전용 객체 속성의 키로 사용된다.
자바스크립트에서 원시값은 변수에 할당될 때, 메모리의 고정 크기로 원시값을 저장하고 해당 저장된 값을 변수가 직접적으로 가리키는 형태를 띈다.
따라서 원시값 자체와, 원시값을 할당한 변수를 혼동하지 않는 것이 중요하다. 변수는 새로운 값을 다시 할당할 수 있지만, 이미 생성한 원시 값은 객체, 배열, 함수와는 달리 변형할 수 없다. 재할당 시 기존 값이 변하는것 처럼 보일지 몰라도 사실 새로운 메모리에 재할당한 값이 저장되고 변수가 가리키는 메모리가 달라졌을 뿐이다.
그렇다면 원시 타입의 값이 복사 될때는 어떤 일이 일어날까?
let a = 100;
let b = a;
a = 50;
console.log(b) // 100
새로운 변수 b의 공간에는 a의 값을 값을 복사하여 변수의 메모리에 담게 된다. 그렇기에 변수 a가 50으로 재할당 되더라도 b는 전혀 영향을 받지 않는다.
객체는 관련된 데이터와 함수(프로퍼티와 메소드)의 집합이다. ( 객체 , 함수 , 배열 )
객체 리터럴 구문을 사용해 제한적으로 속성을 초기화할 수의 있고, 그 후에 속성을 추가하거나 제거할 수도 있다. 속성 값으로는 다른 객체를 포함해 모든 타입을 사용할 수 있으므로 복잡한 자료구조의 구축이 가능하다. 속성은 '키' 값으로 식별하며, 키 값으로는 문자열 값이나 심볼을 사용할 수 있다.
원시타입의 값들은 값이 직접적으로 저장되어 있지만, myArray (참조타입)는 Heap 메모리의 주소값이 저장되어 있다.
객체는 변경 가능한 값으로, 식별자인 변수에 할당할 때 참조 값을 받아서 실제 객체에 접근한다. 또한 원시 값은 변경 불가능하지만 객체는 동적으로 값을 추가하거나 삭제가 가능하기 때문에 값을 변경할 때 기존의 메모리 주소를 그대로 사용한다.
let myArr = [];
let copyArr = myArr;
myArr.push("hello");
console.log(copyArr); // ["hello"]
위 그림에서 보듯이 객체값을 변경할 때 기존의 메모리 주소를 그대로 사용하기 때문에 참조 여부를 잘 고려하지 않은 채 객체나 배열에 수정 및 복사를 하게되면 원본 데이터가 예상치 못한 방향으로 손상 및 변경될 수 있다.
원시 값 | 객체 |
---|---|
변경 불가능한 값(immutable value)이다. | 변경 가능한 값(mutable value)이다. |
변수에 할당하면 변수에는 실제 값이 저장된다. | 변수에 할당하면 변수에는 참조 값이 저장된다. |
다른 변수에 할당하면 원시 값이 복사되어 전달된다. → 값에 의한 전달 | 다른 변수에 할당하면 원본의 참조 값이 복사되어 전달된다. → 참조에 의한 전달 |