You Don't Know JS #1

loopbackseal·2021년 2월 9일
0

YDKJS🧔

목록 보기
2/3
post-thumbnail

Chapter 1. 타입


타입이란?

'타입'이란 자바스크립트 엔진, 개발자 모두에게 어떤 값을 다른 값과 분별할 수 있는, 고유한 내부 특성의 집합이다.

42는 계산을 하려는 의도지만, "42"는 출력할 문자열 비슷한 것으로 쓸 의도로 만든 값이다.


내장 타입

자바스크립트에는 7가지 타입이 있다.

  • null
  • undefined
  • boolean
  • number
  • string
  • object
  • symbol (ES6부터 추가)

이러한 타입은, typeof 연산자를 사용하여 나오는 결과를 통해 확인할 수 있는데, 놀랍게도 7가지 내장 타입과 1:1로 정확히 매치되지 않는다.

이 부분에서 이해하고 넘어가야할 부분은 두가지인데, 그 중 한가지는
typeof null === "object"; // true 라는 점이다.
typeof null === "null" // true 가 맞지만, null을 이용한 하위호환의 유지를 위해 null이 아닌 object가 된다. 따라서 null은 'falsy'한 유일한 원시 값이지만, 특이하게도 타입은 7가지 내장 타입 중 유일하게 원시 타입이 아닌 object인 아리송한 존재이다.

또한 typeofnull을 제외한 6개의 원시 타입 이외에 다른 문자열을 반환한다. 이는 "function"으로, typeof function a(){/* ... */} === "function"; // true 를 통해 확인할 수 있다. 이 결과를 통해 function이 최상위 레벨의 내장 타입처럼 보이지만, function호출 가능한 객체이다. (내부 프로퍼티로 호출할 수 있는 객체, Callable Object) 함수는 인자라는 이름으로 내부에 property를 가질 수 있으며, 해당 인자의 갯수는 length 프로퍼티를 통해 확인할 수 있다.

그렇다면 배열의 typeof는 어떤 값을 가질까?typeof [1,2,3] === "object"; // true 그냥 "object"임을 확인할 수 있다. 배열은 키가 문자열인 객체와 반대로) 숫자 index를 가지며, length ㅡ로퍼티가 자동으로 관리되는 등의 특성을 지닌 객체의 하위 타입이다.


값은 타입을 갖는다

Javascript는 타입 강제를 하지 않는다. 다음과 같은 예시가 가능하다.

var a = "Javascript";
typeof a; // "string"
a = 42;
typeof a; // "number"

따라서, typeof는 "이 변수의 타입은 무엇이니?"라는 질문보다는 "이 변수에 들어있는 값의 타입은 무엇이니?" 라는 질문에 가깝다.


"undefined" vs "undeclared"

"undefined""값이 없는"이라는 의미이고, "undeclared""선언되지 않은"이라는 의미를 갖는다. Javascript에서 이 둘은 완전히 다른 개념이다.

var a;
a; // undefined
b; // ReferenceError: b is not defined

a의 경우, undefined이고, b의 경우 undeclared이지만, 에러 메세지가 b is not defined이기 때문에 사용자들로 하여금 헷갈리게 한다. typeof의 결과는 더하다.

var a;
typeof a; // "undefined"
typeof b; // "undefined"

위의 예시에서 볼 수 있듯, undefinedundeclaredtypeof값은 모두 "undefined"로 같다.


Safety Guard

앞서 확인한 typeof의 독특한 결과를 통해, 개발자들은 여러 스크립트 파일의 변수들이 전역 네임스페이스를 공유할 때, safety guard로서 해당 결과를 사용하기도 한다. DEBUG라는 전역 변수를 플래그로서 사용한다고 가정했을 때, 해당 변수를 사용하기 위해서는 브라우저에서 DEBUG가 사용된 파일을 로딩하면 된다. 하지만 정상적으로 로드가 되지 않은 경우 ReferenceError가 발생하게 되는데, 이 예외처리를 할 때, typeof의 독특한 결과를 이용하면, ReferenceError의 발생을 예방할 수 있다.

// 기존에 이런 식으로 사용을 했다면,
if (DEBUG) {
  console.log("Start DEBUG");
}
// typeof의 독특한 결과를 이용한다면?
if (typeof DEBUG !== "undefined") {
  console.log("Start DEBUG");
}

또 다른 방법은 "모든 전역 변수는 전역 객체의 프로퍼티라는 점"을 이용하는 방법이다.

// 브라우저의 경우, 전역 객체는 window이다!
if (window.DEBUG) {
  console.log("Start DEBUG");
}

특정 객체의 프로퍼티에 대한 접근을 시도했을 때, 프로퍼티가 존재하지 않더라도 javascript는 ReferenceError를 발생시키지 않는다. 하지만, 이 방법은 추천되지 않는 방식이다. 그 이유는 다중 스크립트 환경에서 전역 변수를 꼭 window 객체로만 호출하지 않는 경우 (node.js의 경우 서버에서 실행) 가 존재하기 때문이다.

또한, 일부 개발자들은 typeof를 사용하는 방식 또한 그다지 바람직하지 않다고 한다. 다양한 설계 옵션이 존재하기 때문에, 어떠한 방식이 완전히 맞다, 틀리다고 할 수는 없다. 그럼에도 불구하고, typeof Safety guard를 하나의 옵션으로 사용할 수 있다는 점은 확실하다.

profile
CAU Business Administration

0개의 댓글