はじめに
JavaScriptのコンソールで「undefined」や「null」といった単語を目にしたことはありませんか?
どちらも変数を参照した時のエラー発生時等に出てくるワードですが、この2つの違いは何なのだろう?0(ゼロ)や空文字列(””)とはどう違うの?
といった疑問を初心者の時は特に抱えやすいです。
この記事では、そんなモヤモヤを解決します!
undefinedは「存在しないデータ」
まずundefinedはどんな時に登場するのでしょうか。下記の例を見てください。
var value = 1; console.log(value); //1
このように、変数valueを宣言し、その時に値を代入すればログに出力するために参照されても問題なくその値を表示することができます。しかしこの時、値を代入しないとどうなるでしょうか?
var value; console.log(value); //undefined
上記のように、valueという変数を宣言したけれどもまだ値を何も入れていない場合、この変数の中身を表示しようとしても何も表示できず「undefined」となります。
JavaScriptでは変数の中身に応じたサイズの「入れ物」(メモリのこと)を確保しますが、上記のように、宣言されただけでまだ何の値も入っていない場合はどんなサイズの入れ物を用意すればいいのかわからないため、実はまだ入れ物すら用意されていない状態です。つまりデータとしてまだ存在していません。
また、下記の例も見てください。
var list = {id: 1, name: "apple"}; console.log(list.price); //undefined
listという連想配列に、id、nameというキーがありますね。nameにappleという要素が入っているので、商品管理用か何かのデータと想像してください。
ここに、価格を表すキーがあっても良さそうなので、次の行で「list.price」というふうにpriceというキーを呼び出しています。
しかしそのようなキーは存在せず、ここでもundefinedが返ってきます。
このように、存在していないデータ・または宣言されただけでまだ値の代入がされていないデータを参照しようとした時に返されるのがundefinedです。
nullは「値なし」
undefinedと混同されやすいものに「null」があります。
nullとは「意図的にオブジェクトの値が存在しないことを表す値」です。下記の例を見てください。
var zip1 = "112-0004"; var zip2 = "112004"; var pattern = /^\d{3}-\d{4}$/g; console.log(zip1.match(pattern)); //[ '112-0004' ] console.log(zip2.match(pattern)); //null
上記ではmatchメソッドを用いてパターンとのマッチングを行い、与えられた文字列が郵便番号として成り立つかどうかを確認しています。
matchメソッドは特定のパターンとマッチする文字列があればその文字列を返しますが、もしない場合は何を返すでしょうか?
空の文字列?そうではありません。
あまり無いケースですがもし入力文字列も検索文字列も空文字列「””」であった時、空文字列が見つかりそのまま空文字列が返されることになりますが、ここで「見つからなければ空文字列を返す」というルールだと矛盾が生じてしまうからです。
似たようなことは他のメソッドでもあり得ます。
そこで、「該当はありませんよ」ということを明示的に表すための値が必要です。
これがnullですね。
実際に上記のコードでzip1とzip2という文字列を郵便番号パターンに該当するかどうかmatchメソッドで確かめています。
zip1には該当文字列があったためその文字列が返されていますが、zip2はパターンとマッチする文字列がなかっためnullが返ってきていますね。
注意したいのが、このzip1.match(pattern)もzip2.match(pattern)もそれぞれmatchメソッドの返り値として存在するデータであり、前者には文字列が、後者にはnullが入っているということです。
このように、データとして存在はしているが「値なし」であることを明示的に示すための値がnullです。
0や空文字列””は「値あり」
同じようにundefinedやnullと混同されがちなのが0(ゼロ)や空文字列(””)です。
立派な値としての0・空文字列
ゼロや空文字列は立派な値です。
nullも値ですが、先述の通り「値なし」を表す特殊な値でした。undefinedはそもそもデータとして存在しないことを表します。
例として山田さん・鈴木さん・佐藤さんからなるクラスでテストを実施したとしましょう。
山田さんの点数は70点、鈴木さんは0点、佐藤さんは遅刻したためテストを受けられませんでした。
ここで、田中さんの点数は何点でしょう?鈴木さんは?佐藤さんは?
答えは順に「undefined、0、null」となります。田中さんはこのクラスに存在していないですし、佐藤さんは存在していますがテストを受けられなかったので点数はつけられません。
鈴木さん(と山田さん)だけがテストの点数という値を持っていて、0点ではありますがこれもれっきとした点数であり、ここが田中さん(undefined)や佐藤さん(null)との違いです。
混同されやすい理由
なぜこれらは混同されやすいのでしょうか。それはよく条件分岐などで書かれる下記の記述が原因かもしれません。
if(!data) { //処理; }
このdataには例えば新規メールの件数が入っていて、もし新しいメールが来ていたら読み上げる処理をするといったことができます。
もしくはdataには何かのアンケートの備考欄に書かれた内容が入っていて、もし何か入力されていたらアラートを出すといったこともできますね。
いずれもdataがゼロだったり空文字列だったりするとその処理をする必要がないため上記のコードのように「!dataが正ならばこの処理をする」(!dataで「dataの否定」という意味になります)と書かれるのが一般的です。
同様に、dataがそもそも存在しないデータ(undefined)だったり、nullが入っていてもこの書き方ではじいて処理をさせないようにできます。
実際に、真偽判定(trueかfalseか判定すること)では下記の通り全て偽(false)となります。
console.log(0 == true); //false console.log("" == true); //false console.log(null == true); //false console.log(undefined == true); //false
そのため、この4つ(undefined・null・0・””)は同じなのでは?と混同されやすいようです。
しかし、先述の通りれっきとした違いがありますので混同しないように注意しましょう。
まとめ
undefined・null・ゼロ(と空文字列)の違いを解説しました。
初心者の時にはなかなか掴みにくい概念ですが、少しでも理解の助けになれば幸いです。
今すぐにわからなくても書きながら次第に理解が進んでいきますので、頑張りましょう!
動画でプログラミング入門をしよう
オンライン学習サービスProglus(プログラス)でプログラミングを学び、創れる人になろう!
プレミアムプランを2週間無料体験しよう
今すぐ詳細を確認する