【TypeScript】nullとundefinedを改めて整理する
どうもフロントエンドエンジニアのoreoです。
この記事ではnullとundefinedの違いについて整理します。人に説明する時に違いがパッと思い出せなかったので、忘れないように書きたいと思います。
1 nullとundefinedについて
nullとundefinedは、それぞれ「データがない」ことを意味するプリミティブです。それぞれnull、undefinedという値と型をもちます。
2 null vs undefined
2-1 発生のタイミング
nullは基本的に自然発生しないので、意図を持って代入することが必要です(※)。
一方で、undefinedは、自然に発生するもので、例えば変数宣言時に初期化しなかった場合、オブジェクト・配列の存在しないプロパティ・要素にアクセスした場合などに、undefinedになります。
(※)一部のDOM系のAPIはnullを返す時があるのでライブラリのよってはnullを返すことがあります。
//変数宣言時に初期化しない場合
let test;
console.log(test); //undefined
//オブジェクト・の存在しないプロパティにアクセスした場合
let Obj = { test: "test" };
console.log(Obj.test2); //undefined
//配列の存在しないい要素にアクセスした場合
let Array = ["test"];
console.log(Array[1]); //undefined
//返り値の無い関数の場合
function func() {
console.log("test");
}
console.log(func()); //undefined
2-2 変数としての扱い
nullはリテラルな一方で、undefinedは変数。
let null; //エラー「Unexpected token」!!
undefinedは変数なので書き換えることが可能。
console.log(undefiend); //undefiend
let undefiend = "test";
console.log(undefiend); //test
2-3 typeof演算子の結果
typeof演算子は、typeof 式
のような形で式を評価し、その評価結果に応じて以下表「結果」のような文字列を返します。nullの場合は、”object”を返し、undefinedの場合は、”undefined”を返します。
2-4 等価演算子と厳密等価演算子
等価演算子は、nullとundefinedを比較した時に、trueを返します。一方で、厳密等価演算子は、nullとundefinedを比較した時に、方が異なるのでfalseを返します。
//等価演算子
console.log(null == null);//true
console.log(null == undefined);//true
console.log(undefined == undefined);//true
//厳密等価演算子
console.log(null === null);//true
console.log(null === undefined);//false!!!!
console.log(undefined === undefined);//true
2-5 JSON.stringify()
JSON.stringify()
は、オブジェクトや値をJSON文字列に変換してくれます。オブジェクトのプロパティにnullが存在していた場合は、JSON文字列に変換されるが、undefinedが存在していた時にJSON文字列に変換されず、そのプロパティは削除さる。
//オブジェクトでJSON.stringify()を使用した場合
//undefinedのプロパティは削除される
let nullObj = {
test: null
};
let undefinedObj = {
test: undefined
};
console.log(JSON.stringify(nullObj)); //{"test":null}
console.log(JSON.stringify(undefinedObj)); //{}
//配列でJSON.stringify()を使用した場合
//配列では、undefinedの要素は削除されない
let nullArray = [null, "test"];
let undefinedArray = [undefined, "test"];
console.log(nullArray); //[null, "test"]
console.log(undefinedArray); // [undefined, "test"]
3 nullとundefinedのどちらを使うのか?
状況によって違うので一概には言えませんが、undefinedが推奨されています(TypeScriptのコーディングガイドラインにもその旨の記載あり👇)。チームルールとして、どちらかに寄せていく場合は、undefinedはさまざまな場面で発生する為、undefiendに寄せる方が簡単という考え方もある模様です。
4 最後に
JSON.stringify()
の挙動は初めて知りました。この記事で取り上げた以外にも細かい違いがあると思いますが、2-1の発生のタイミングや3の使い分けに関しては、押さえておきたいですね!
5 参考
Discussion