# Null vs. Undefined

> [관련 무료 영상](https://www.youtube.com/watch?v=kaUfBNzuUAI)

자바스크립트와 타입스크립트에는 두가지 타입이 있습니다. `null`과 `undefined`는 다른것들을 의미합니다.

* 무엇인가가 초기화 되지 않았습니다. : `undefined`.
* 무엇인가를 초기화 후 의도적으로 null값을 할당했습니다: `null`.

## null과 undefined 둘중 하나를 확인

다음은 자바스크립트의 `==`를 이용해서 `null`과 `undefined`를 비교했을때 각각 결과값을 보여줍니다.

```typescript
// null과 undefined는 `==`를 사용해도 일치합니다.
console.log(null == null) // true (of course)
console.log(undefined == undefined) // true (of course)
console.log(null == undefined) // true

// 다음과 같은 경우는 false값을 반환합니다.
console.log(0 == undefined) // false
console.log('' == undefined) // false
console.log(false == undefined) // false
```

null을 확인할 경우에는 `== null`와 같이 동등연산자를 사용하여 비교하는 것을 추천합니다. 일반적으로 `undefined`와 `null`을 비교할일은 거의 없습니다.

```typescript
function foo(arg: string | null | undefined) {
    if (arg != null) {
        // arg must be a string as `!=` rules out both null and undefined.
    }
}
```

> 당신은 `== undefined`을 사용해서 비교할 수도 있지만 `== null`을 사용하는 게 짧고 더 흔하게 사용됩니다.

다음은 최상단에서 `undefined`값에 대해서 예외처리에 대해서 알아봅니다.

## 최상단에서 undefined 확인

나는 당신에게 `== null`를 비교할때 동등연산자를 사용하라고 말했습니다. 최상단에서 비교할때는 이것을 사용하면 안됩니다. strict mode에서 사용하게 되면 `foo`가 정의되지 않은 경우 `ReferenceError`가 발생하며 전체 호출 스택이 해제됩니다.

> 당신은 strict mode를 사용해야 합니다. 타입스크립트는 컴파일러는 strict mode를 당신이 사용하는 모듈에 삽입하기 때문입니다.

전역변수가 정의됐는지 `typeof`를 사용해서 확인할 수 있습니다.

```typescript
if (typeof someglobal !== 'undefined') {
    // 전역에서 사용해도 안전합니다.
    console.log(someglobal)
}
```

## `undefined`는 명시적으로 사용하는 걸 제한해야 합니다.

왜냐하면 타입스크립트는 별도로 구조를 문서화할 수 있는 기회를 제공하기 때문입니다.

```typescript
function foo() {
    // if Something
    return { a: 1, b: 2 }
    // else
    return { a: 1, b: undefined }
}
```

당신은 타입 주석을 사용해야 합니다.

```typescript
function foo(): { a: number; b?: number } {
    // if Something
    return { a: 1, b: 2 }
    // else
    return { a: 1 }
}
```

## 노드 방식 콜백

노드 방식에서 콜백함수는 (예: `(err,somethingElse)=>{ /* something */ }`) 일반적으로 `err`는 `null`로 설정된 에러를 가지고 호출하며 truthy 확인을 사용합니다.

```typescript
fs.readFile('someFile', 'utf8', (err, data) => {
    if (err) {
        // do something
    } else {
        // no error
    }
})
```

자신의 API를 만들때 일관성을 위해서 `null`을 사용하는게 좋습니다. 자신의 모든 API에 대해서 에러를 `.then` vs. `.catch`를 사용해서 처리해야 합니다.

## `undefined`를 유효성을 나타내는 수단으로 사용하지 마십시요.

예를 들어 이런 끔찍한 함수가 있습니다.

```typescript
function toInt(str: string) {
  return str ? parseInt(str) : undefined;
}
```

이렇게 쓰는게 더 좋을 수 있습니다. can be much better written like this:

```typescript
function toInt(str: string): { valid: boolean; int?: number } {
    const int = parseInt(str)
    if (isNaN(int)) {
        return { valid: false }
    } else {
        return { valid: true, int }
    }
}
```

## JSON 그리고 serialization

JSON 표준은 null인코딩을 지원하지만 정의되지는 않습니다. JSON이 `null`속성으로 객체를 인코딩할때 값으로 포함되는 반면에 `undefined`는 제외됩니다.

```typescript
JSON.stringify({ willStay: null, willBeGone: undefined }) // {"willStay":null}
```

결과는 JSON 기반 데이터베이스는 `null`값을 지원하지만 `undefined`는 지원하지 않습니다. 속성값을 `null`을 이용하여 속성을 지울 수 있습니다.

속성값을 `undefined`를 이용하면 저장소 비용을 절약할 수 있습니다. 하지만 의미론적으로 볼때 이러한 방법은 더 복잡하게 만들 수 있습니다.

## 결론

타입스크립트팀은 `null`을 사용하지 않습니다. [타입스크립트 코딩 가이드](https://github.com/Microsoft/TypeScript/wiki/Coding-guidelines#null-and-undefined) 그럼에도 아무런 문제가 발생하지 않았습니다. 더글락스 크록포드는 `null`을 사용하는 것이 안좋은 생각이라고 말했습니다. [`null`을 사용하지 말아야 할 이유](https://www.youtube.com/watch?v=PSGEjv3Tqo0\&feature=youtu.be\&t=9m21s) 우리는 모두 `undefined`을 사용해야 합니다.

그러나 NodeJS 스타일 코드는 에러 매개변수를 `null`을 표준으로 사용합니다. 나는 개인적으로 두 프로젝트를 구별하는 것을 신경쓰지 않습니다. 대부분의 프로젝트가 서로 다른 라이브러리를 사용하고 `== null`로 배제하기 때문입니다.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://radlohead.gitbook.io/typescript-deep-dive/recap/null-undefined.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
