YOU DON'T KNOW JS #01
자바스크립트 같은 동적 언어는 타입(Type) 개념이 없다고 생각하는 개발자가 많다.
1. 타입, 그 실체를 이해하자
'타입'이라는 정의로 살펴보면 어떤 값을 다른 값과 분별할 수 있는 고유한 내부 특성이 있다면, 타입이 있다고 할 수 있다.
자바스크립트라는 언어에서 '강제변환(coercion)'이 일어나기 때문에 타입을 확실하게 인지하고 사용하는 것은 중요하다.
2. 내장 타입
자바스크립트에는 7가지 내장 타입이 있다. -> null, undefined, boolean, number, string, object, symbol
(이들 중 object를 제외하고 '원시타입(primitives)' 이라고 한다.)
그럼 typeof연산자로 타입을 알아보자.
우리는 typeof의 반환값은 항상 7가지 내장 타입 중 하나일 것이라고 생각할 것이다.
하지만, 결과는 그렇지 않다.
typeof null === "object"; // true
null은 null을 반환해야 한다. 이 버그는 20년동안 함께 해왔고, 이제 와서 바꾸기엔 side effect로 웹 소프트웨어가 멈춰버릴 경우가 너무 많기 때문에 앞으로도 해결될 가능성은 없을 것 같다.
그래서, 우리는 타입으로 null값을 정확하게 확인하기 위해 조건이 하나 더 필요하다.
let a = null;
(!a && typeof a === "object"); // true
null은 'falsy'한 유일한 원시 값이지만, 타입은 'object'인 특별한 존재이다.
typeof function a(){ } === "function"; // true
typeof [1, 2, 3] === "object"; // true
함수와 배열은 객체의 '하위 타입' 이다.
3. 값은 타입을 가진다.
변수는 타입이 없지만 값은 타입이 있다. 타입은 값의 내재된 특성을 정의한다.
변수는 언제라도, 어떤 형태의 값이라도 가질 수 있다. 자바스크립트는 'Type Enforcement(타입 강제)'를 하지 않기 때문에, 변숫값이 처음에 할당된 값과 동일한 타입일 필요는 없다.
변수에 typeof 연산자를 사용하는 것은 "이 변수에 들어있는 값의 타입은 무엇이니?"라고 묻는 것과 같다.
1) 값이 없는 vs 선언되지 않은
값이 없는 변수의 값은 undefined, typeof 결과는 "undefined"이다.
let a;
typedof a; // "undefined"
let b = 42;
let c;
b = c;
typedof b; // "undefined"
typeof c; // "undefined"
"undefined"(값이 없는)는 접근 가능한 스코프에 변수가 선언되었으나 현재 아무런 값도 할당되지 않은 상태를 가리킨다.
let a;
a; // undefined
b; // ReferenceError: b is not defined
"undeclared"(선언되지 않은)는 접근 가능한 스코프에 변수 자체가 선언조차 되지 않은 상태를 의미한다.
여기서 브라우저 에러 메시지가 다소 헷갈릴 수 있는 부분이다.
"b is not defined"는 결국 "b is not found"나 "b is not declared"라고 생각하면 된다.
let a;
typeof a; // "undefined"
typeof b; // "undefined"
선언되지 않은 변수의 typeof 연산 결과는 우리를 더 헷갈리게 한다. 선언되지 않은 변수도 "undefined"로 나오기 때문이다.
분명, b는 선언조차 하지 않은 변수인데, typeof b는 오류를 뱉지 않는다. 이것이 typeof만의 안전가드(safety guard)이다.
2) 선언되지 않은 변수
이 안전가드는 브라우저에서 자바스크립트 코드를 처리할 때, 특히 여러 스크립트 파일의 변수들이 전역 namespace(네임스페이스)를 공유할 때 쓸모가 있다.
ReferenceError가 나지 않게 전역 변수를 체크해야 할 때, typeof 안전 가드가 제 몫을 해낸다.
// error
if (DEBUG) {
console.log("디버깅을 시작합니다");
}
// 이렇게 사용하면 안전하게 존재 여부 체크 가능
if (typeof DEBUG !== "undefined") {
console.log("디버깅을 시작합니다");
}
이런 식으로 체크하는 것이 내장 API기능을 체크할 때에도 에러가 나지 않게 도와준다.
위 내용은 카일 심슨의 저서 YOU DON'T KNOW JS의 내용을 발췌한 것입니다.
'개발도서' 카테고리의 다른 글
[Clean Code] #1 깨끗한 코드 (0) | 2023.08.04 |
---|---|
YOU DON'T KNOW JS #02 (0) | 2021.07.20 |