【JavaScript / TypeScript】null と undefined の違いと使い分けを考える

# はじめに
``TypeScript``での``null``と``undefined``の使い分け方に対する考えと、``null``と``undefined``の違いについて、自分なりに調べて学んだことを書いた記事です。

# 結論どっちを使うべきか
**``undefined``を積極的に利用していくべき**
（``null``の利用を避けられない場合を除いて）

ではないか、という結論になりました。

``TypeScript``開発チームのGithub wiki にあるコーディングガイドにも

>Use undefined. Do not use null.

「``null``は使用せず、``undefined``を使用してください。」
と記載されています。
（あくまで``TypeScript``の開発チーム内での決め事ではありますが、）

https://github.com/Microsoft/TypeScript/wiki/Coding-guidelines#null-and-undefined

# null と undefined の違い
``null``も``undefined``もプリミティブ型の値の一つ。
どちらも「値が存在しない」ことを表現するものであるものの、``null``と``undefined``には明確な違いがある。

## 意味合いでの違い
**null**: 代入すべき値が存在しないため、値がない（変数がメモリに対する参照を保持しない）
**undefined**: 値が代入されていないため、値がない（変数が未定義である、初期化されていない）

## 言語使用上での違い
## nullは自動的に設定されないが、undefinedは自動的に設定される
**null**: 開発者が意図的に設定しない限り設定されない。
**undefined**: 開発者が意図しなくても、自動的に設定される。

```js
// 変数を宣言したときに初期値が存在しなければ、その変数にundefinedが設定される。
let value;
console.log(value); //=> undefined
```

```js
// オブジェクトに存在しないプロパティや配列にない要素にアクセスしたときも、自動的にundefinedになる。
const obj = {};
console.log(obj.foo); //=> undefined
const arr = [];
console.log(arr[0]); //=> undefined
```

```js
// 戻り値がない関数の戻り値を取得したときもundefinedになる。
function func() {}
console.log(func()); //=> undefined
```

## nullはリテラル、undefinedは変数
**null**: [リテラル](https://wa3.i-3-i.info/word15346.html)なのでnullという名前の変数を作ることはできない。
**undefined**: 変数なので``undefined``という変数を作ることができる。（グローバルより内側のスコープに限る）

※ ちなみに``window``オブジェクト（グローバルオブジェクト）は``undefined``というプロパティを持っている。この初期値は``undefined``。

|コンソール（Google Chromeディベロッパーツール）|
|-|
|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621162/7c7bab83-0ee4-18e6-7b19-2c2f3ae481a2.png" width="300" />|


## typeof の挙動
```js
typeof null          // "object" (歴史的な理由で "null" ではないらしい)
typeof undefined     // "undefined"
```

## isNaN の挙動
```js
isNaN(1 + null)      // false
isNaN(1 + undefined) // true
```

## JSON での挙動
**null**: 設定できる。
**undefined**: 設定できない。

```js
console.log(JSON.stringify({ foo: undefined })); //=> {}
console.log(JSON.stringify({ foo: null })); //=> {"foo": null}
```

# おまけ
## == と === で比較
```js
null === undefined   // false
null  == undefined   // true
```

# まとめ
冒頭でも述べた通り、``TypeScript``での開発では
``null``の利用を避けられない場合を除いて、``undefined``を積極的に利用していくべき、かなと考えました。

理由としては、
「値が存在しない」ことを表現する方法を、「自動的に発生してしまう``undefined``」に寄せた方が統一しやすいから、と思いました。（日本語難しい...）

ただ一方で、``null``を返すAPIなどのハンドリングをする場合などは``null``の利用を避けられなかったりするので、完全に``null``を利用しないことは難しいのかもしれない。

非常に参考にさせていただいたこちらの資料では

https://typescriptbook.jp/reference/values-types-variables/undefined-vs-null


>使い分け意識を育てる労力は、それに見合うメリットが少ない

との記載もあります。

# 最後に
間違い、ご指摘などございましたらコメントお願いします！！

### 参考
ありがとうございました！！！

- https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/null
- https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/undefined
- https://typescriptbook.jp/reference/values-types-variables/undefined-vs-null
- https://typescript-jp.gitbook.io/deep-dive/recap/null-undefined
- https://github.com/Microsoft/TypeScript/wiki/Coding-guidelines#null-and-undefined
- https://www.amazon.co.jp/%E7%8B%AC%E7%BF%92JavaScript-%E6%96%B0%E7%89%88-CodeMafia-%E5%A4%96%E6%9D%91-%E5%B0%86%E5%A4%A7/dp/479816027X/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=%E7%8B%AC%E7%BF%92JavaScript&qid=1639187025&s=books&sr=1-1