이번 포스팅에서는 자바스크립트의 타입과 값에 대한 내용을 정리해 보려고 한다. 기본적인 내용이라 대부분의 자바스크립트 개발자라면 어느 정도 알고 있을만한 내용이지만, 어렴풋이 알고 있는 개념들을 확실하게 정리하고 넘어가기 위해 이 글을 작성했다.
자바스크립트에는 7가지 내장 타입이 있다.
- null
- undefined
- boolean
- number
- string
- object
- symbol(ES6)
값 타입은 typeof로 알 수 있는데 다른 타입들은 정확하게 매치가 되고 null만 type이 object로 매칭된다. 그리고 자바스크립트 내장 타입에는 없지만 typeof가 반환하는 문자열 중에는 "function"도 있다. function은 object의 하위 타입이다.
typeof true === "boolean"; // true
typeof 42 === "number"; // true
typeof "a" === "string"; // true
typeof { name: "alex" } === "object"; // true
typeof undefined === "undefined"; // true
typeof Symbol() === "symbol"; // true
typeof null === "object"; // true
typeof function a(){ /* ... */ } === "function"; // true
자바스크립트에서 값이 없는 변수는 undefined 값을 가진다. 이는 선언되지 않은(undefined) 값과 혼동하기 쉬운데 완전하게 다른 개념이다.
var a;
a; // undefined
b; // ReferenceError: b is not defined
// typeof를 쓰면 조금 혼란스럽다.
typeof a; // "undefined"
typeof b; // "undefined"
특수 값 중에 많은 개발자들이 혼동하는 개념이 null과 undefined이다. Undefined 타입의 값은 undefined 밖에 없고, null 타입도 값은 null 뿐이다. 개발자들은 보통 null이 빈 값이고, undefined는 실종된 값이라고 생각하는 경우가 많다. 아니면 null은 예전에는 있었지만, 지금은 없는 값이고, undefined는 값을 아직 가지지 않은 것이라고 생각하기도 한다. 어떻게 생각하든 둘의 차이만 잘 기억하고 있으면 상관없다.
다른 언어에서 값은 사용하는 구문에 따라 값 복사(Value Copy), 참조 복사(Reference Copy)의 형태로 할당 또는 전달된다. C++과 같은 언어는 어떤 함수에 전달한 숫자 인자값을 그 함수 내에서 수정하려면 int& myNum 형태로 함수 인자를 선언하고, 호출하는 쪽에서는 변수 x를 넘기면 myNum은 x를 참조한다. 레퍼런스는 포인터의 특수한 형태로 다른 변수의 포인터를 가진다. 레퍼런스 인자를 선언하지 않으면 전달한 값은 아무리 복잡한 객체일지라도 언제나 복사된다.
자바스크립트는 포인터 개념도 없고 참조하는 방법도 이러한 언어와 다르다. 어떤 변수가 다른 변수를 참조하는 것이 아예 안 된다. 자바스크립트에서 레퍼런스는 (공유된) 값을 가리키므로 서로 다른 10개의 레퍼런스가 있다면 이들은 저마다 항상 공유된 단일 값을 개별적으로 참조한다.
자바스크립트는 값의 타입만으로 값 복사, 참조 복사 중 한쪽이 결정된다. null, undefined, string, number, boolean, symbol은 값 복사 방식으로 할당, 전달 된다. 반면 객체(object)나 함수(function) 등 합성 값은 할당, 전달 시 반드시 레퍼런스 사본을 생성한다.
var a = 2;
var b = a;
b++;
a; // 2
b; // 3
var c = [1,2,3];
var d = c;
d.push(4);
c; // [1,2,3,4]
d; // [1,2,3,4]
위의 예제에서 a와 b에는 다른 사본이 들어가기 때문에 동시에 값을 바꿀 수는 없다. 반면 c,d는 모두 합성 값이며 동일한 공유 값 [1,2,3]에 대한 개별 레퍼런스이다. 여기서 c와 d는 값을 소유하는 것이 아닌 동등하게 [1,2,3]을 참조한다는 사실을 기억해야 한다. 따라서 레퍼런스로 공유한 값이 변경되면, 두 레퍼런스는 변경된 값을 동시에 바라보게 되는 것이다.
참고자료
- <YOU DON'T KNOW JS (타입과 문법, 스코프와 클로저)> 카일 심슨 저
'Prog. Langs & Tools > JavaScript' 카테고리의 다른 글
JS #14. 스코프(Scope) (0) | 2020.09.07 |
---|---|
JS #13. 네이티브 객체(Native Objects) (0) | 2020.08.04 |
JS #11. 자바스크립트 제너레이터(Generator) (0) | 2020.06.19 |
JS #10. 자바스크립트 프로미스(Promise) (0) | 2020.06.11 |
JS #9. 자바스크립트 콜백(Callback) (1) | 2020.06.01 |