YOU DON'T KNOW JS #01

2021. 7. 19. 01:16

자바스크립트 같은 동적 언어는 타입(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

BELATED ARTICLES

more