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


はじめに

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

結論どっちを使うべきか

undefinedを積極的に利用していくべき
nullの利用を避けられない場合を除いて)

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

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

Use undefined. Do not use null.

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

null と undefined の違い

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

意味合いでの違い

null: 代入すべき値が存在しないため、値がない(変数がメモリに対する参照を保持しない)
undefined: 値が代入されていないため、値がない(変数が未定義である、初期化されていない)

言語使用上での違い

nullは自動的に設定されないが、undefinedは自動的に設定される

null: 開発者が意図的に設定しない限り設定されない。
undefined: 開発者が意図しなくても、自動的に設定される。

// 変数を宣言したときに初期値が存在しなければ、その変数にundefinedが設定される。
let value;
console.log(value); //=> undefined
// オブジェクトに存在しないプロパティや配列にない要素にアクセスしたときも、自動的にundefinedになる。
const obj = {};
console.log(obj.foo); //=> undefined
const arr = [];
console.log(arr[0]); //=> undefined
// 戻り値がない関数の戻り値を取得したときもundefinedになる。
function func() {}
console.log(func()); //=> undefined

nullはリテラル、undefinedは変数

null: リテラルなのでnullという名前の変数を作ることはできない。
undefined: 変数なのでundefinedという変数を作ることができる。(グローバルより内側のスコープに限る)

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

コンソール(Google Chromeディベロッパーツール)

typeof の挙動

typeof null          // "object" (歴史的な理由で "null" ではないらしい)
typeof undefined     // "undefined"

isNaN の挙動

isNaN(1 + null)      // false
isNaN(1 + undefined) // true

JSON での挙動

null: 設定できる。
undefined: 設定できない。

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

おまけ

== と === で比較

null === undefined   // false
null  == undefined   // true

まとめ

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

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

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

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

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

との記載もあります。

最後に

間違い、ご指摘などございましたらコメントお願いします!!

参考

ありがとうございました!!!