자바스크립트는 2가지의 타입이 있다.
원시 타입: 값에 의한 전달(passed by value) 되며 종류로는 Boolean
, Null
, Undefined
, String
, Number
가 있으며 변경이 불가능한 값이다.
객체 타입: 참조에 의한 전달(passed by reference) 되며, 원시 타입 이외의 모든 값은 객채(Object) 타입이며 변경 가능한 값이다. 즉, 객체는 새로운 값을 다시 만들 필요없이 직접 변경이 가능하다.
각 데이터 타입에대해 좀더 자세히 알아보자.
원시 타입의 '값'은 변경 불가능한 값(Immutable Value)이다.
변경이 불가능한 값이라는게 뭘까?
자바스크립트에서는 '값' 을 저장하기 위해 메모리 공간을 확보하고 이 메모리 공간들을 식별하기 위해 이름을 붙인 이름이 '변수' 이다.
즉, 변경이 불가능하다는 것은 변수가 아니라 값 자체를 말하는 것이다.
원시 값은 변경 불가능한 값, 읽기 전용 값이다.
var name;
name = 'kim';
name = 'park';
다음 코드의 메모리 공간을 그림으로 살펴보자.
이처럼 자바스크립트에서는 name
변수를 선언과 동시에 빈공간 메모리가 만들어지며 undefined 을 가진 메모리 공간을 name
변수가 참조하고
name
변수에 kim 이라는 원시 값을 재할당해주면 새로운 메모리 공간이 생성되어 kim 값을 저장 후 name
변수가 참조하던 메모리 공간의 주소를 변경한다.
park
도 마찬가지다.
객체(참조) 타입의 값, 즉 객체는 변경 가능한 값(Mutable Value)이다.
위에서 살펴본 원시 값을 할당한 변수는 원시 값이 저장된 메모리 공간을 기억하고 있으므로, 변수를 통해 메모리 공간에 접근하면 원시 값 에 접근할 수 있다.
하지만 객체 타입을 할당한 변수를 통해 메모리 공간에 접근하면 주소 값 에 접근할 수 있다.
그림을 보면 obj 변수는 0x000000F2 메모리 공간에 할당되어있는데, 이 메모리는 객체가 할당된 변수 0x00001331 참조 값을 통해 객체에 접근하고 있다.
원시 타입과 객체 타입의 이러한 차이때문에
일반적으로 원시 값을 할당한 변수를 "변수는 X값을 갖는다"라고 표현하는 반면,
객체를 할당한 변수는 "변수는 객체를 참조하고 있다.(가리키고 있다)"라고 표현한다.
원시 값은 변경 불가능한 값이므로 원시 값을 갖는 변수의 값을 변경하려면 무조건 변수에 값을 재할당 하여야 한다.
하지만 객체는 변경 가능한 값이므로 객체를 할당한 변수는 재할당 없이 객체를 직접 변경할 수 있다.
즉, 재할당 없이 프로퍼티를 동적으로 추가할 수도 있고 프로퍼티 값을 갱신할 수도 있으며, 삭제할 수도 있다.
obj.age = 30; //age 프로퍼티 추가
obj.name = 'park'; //프로퍼티 값 갱신
delete obj['age'] //프로퍼티 삭제
이때 객체를 수정할 때 변수에 재할당을 하지 않았으므로 객체를 할당한 변수의 주소 값(0x00001331)은 변경되지 않는다.
📚Reference
4. React memo(), useCallback()
원시 타입과 참조 타입