JavaScript 언어의 타입은 원시값과 객체로 나뉜다.
객체를 제외한 모든 타입은 불변 값을 정의한다. 예를 들어 문자열은 불변한다. 이런 타입을 원시값이라고 하고, 그 종류는 다음과 같다.
1. Boolean 타입
2. Null타입
3. Undefined 타입
4. Number 타입
5. Biglnt 타입
6. String 타입
7. Symbol 타입
JS에서 원시값이란 객체가 아니면서 메서드도 가지지 않는 데이터를 말한다.
모든 원시 값은 불변하여 변형할 수 없다. 원시값 자체와, 원시값을 할당한 변수를 혼동하지 않는 것이 중요하다. 변수는 새로운 값을 다시 할당할 수 있지만, 이미 생성한 원시값은 객체, 배열, 함수와는 달리 변형할 수 없다.
다음 예제는 원시값이 불변함을 이해하는데 도움이 된다.
// 문자열 메서드는 문자열을 변형하지 않음
var bar = "baz";
console.log(bar); // baz
bar.toUpperCase();
console.log(bar); // baz
// 배열 메소드는 배열을 변형함
var foo = [];
console.log(foo); // []
foo.push("plugh");
console.log(foo); // ["plugh"]
// 할당은 원시 값에 새로운 값을 부여 (변형이 아님)
bar = bar.toUpperCase(); // BAZ
원시값을 교체할 수는 있지만, 직접 변형할 수는 없다.
다음 예제는 JS가 원시값을 활용하는 방식을 이해하는데 도움을 준다.
// 원시 값
let foo = 5;
// 원시 값을 변경해야 하는 함수 정의
function addTwo(num) {
num += 2;
}
// 같은 작업을 시도하는 다른 함수
function addTwo_v2(foo) {
foo += 2;
}
// 원시 값을 인수로 전달해 첫 번째 함수를 호출
addTwo(foo);
// 현재 원시 값 반환
console.log(foo); // 5
// 두 번째 함수로 다시 시도
addTwo_v2(foo);
console.log(foo); // 5
보다시피 두 함수의 결과는 7이 아닌 5가 된다.
이는 JS가 함수에서 변수를 활용하는 방식에서 기인한다.
addTwo
의 num
, addTwo_v2
의 foo
).foo
에 전혀 영향을 주지 않는다.
컴퓨터 과학에서 객체란 식별자로 참조할 수 있는 메모리 상의 값을 말한다.
상기 JS의 변수 활용방식에 대한 예제 속에서 두번째 함수를 구동할 때, 함수 내에서 인수로 활용된 foo
와 외부에서 선언 된foo
와의 단절성을 볼 수 있었다. 이 경우, 외부 foo
변수에는 어떤 방법으로도 접근할 수 없었다. 이는 JS의 어휘적 유효 범위(lexical scoping)와 결과 변수 섀도잉 때문이라고 하는데. 이에 대해 더 알아보기 위해서
- 어휘적 유효범위(lexical scoping)
- 변수 섀도잉
- 클로저(closure)
에 대해서 알아보기로 한다.
그리고, 자바스크립트의 타입 중 하나인 객체에 대해서도 추가로 알아보기로 한다.