みなさんこんにちは!Kotonoです。今回は、JavaScriptにおける「NaN」について解説をしたいと思います。
この記事では
- NaNとは
- NaNの発生条件について
- NaNの基本的なプロパティ
- NaNの判定方法
- NaN、undefined、nullの違いについて
など、基本的な内容から、より発展的な内容に関してもわかりやすく解説していきたいと思います。
「NaN」とは
みなさんは「NaN」が何か知っていますか?
NaNとはNot-a-Numberの略で、JavaScriptにおける非数(数字ではないもの)を表す、特別な値です。一般的には、数値を期待していたけど実は数値ではなかった場合の結果として使われることが多いです。
注意すべき点は、NaNとは先述した通り「値」ということです。なので、typeof演算子でNaNのデータ型を調べるとNumberと返ってきます。値は非数を表すものの、Infinityなどと同じようにNumber型に属している値だということを覚えておきましょう。
NaNの発生条件について
では、「NaN」という値はどのような時に出現するのでしょうか。NaNはその名の通り「数字ではない」ので、何らかの計算処理によって数値以外の値が発生した時に出現します。
具体的には…、
- ゼロ同士の除算
- NaN値との算術
- Infinity値との定義されていない算術
- その他の無効な演算
などが挙げられます。では、実際に上記のような演算を行い、NaNを出力させてみましょう。
以下のコードをご覧ください。
var res1 = 0/0 var res2 = 10 + NaN; var res3 = Infinity*0 var res4 = Math.sqrt(-3) console.log(res1) console.log(res2) console.log(res3) console.log(res4)
実行結果は以下の通りです。
NaN NaN NaN NaN
上のコードでは、変数res1にゼロ同士の除算の結果、res2に整数10とNaN値の足し算の結果、res3にInfinity値を0で掛けた結果、res4にマイナス3の平方根の値を格納しました。そして、それぞれの変数の中身をconsole.log関数を用いて表示させてみました。
すると、どれもNaNと表示されましたね。
NaNの基本的なプロパティ
NaNは少し特殊な性質を持っています。
一つ目は「NaN値と数字との算術結果は全てNaNとなる」という事です。これは、先ほどもお見せしたように、10+NaNなどの演算は全てNaNという結果になります。
そして二つ目は「NaN値との比較は全てFalseを返す」という事です。
以下のコードをご覧ください。
var res1 = 0/0 console.log(res1==NaN) console.log(res1<0) console.log(res1>0) console.log(res1==0) console.log(res1!=NaN)
実行結果は以下の通りです。
false false false false true
上のコードでは、res1にゼロ同士の除算の結果であるNaN値を格納し、等値比較や大小比較を行いました。NaN値を格納するres1はNaNと等しいとは判断されず、ゼロより小さいとも大きいとも、ゼロに等しいとも判断されませんでした。
唯一trueを返した比較は「res1はNaNとは等値ではない」という、最後の一行です。
NaNの判定方法
では、このセクションではNaNかどうかを識別する方法をご紹介いたします。NaNの判定においては、主にisNaN関数を使用します。
「isNaN()」で判定する方法
isNaN関数とは引数に指定した値がNaNであるか確かめるために使用されるものです。
構文はとてもシンプルで
isNaN(テストしたい値)
となっており、戻り値はtrueかfalseのどちらかを返します。
以下のコードをご覧ください。
var res1 = 0/0 var test1 = isNaN(res1) console.log(test1)
実行結果は以下の通りです。
true
上のコードでは、NaN値を格納するres1をisNaN関数の引数に指定してみました。実際、ゼロ同士の除算はNaNを返したので、trueと表示されました。
「isNaN()」の問題点
さて、isNaN()を使うと「NaN」を判定できるわけですが、必ずしもNaNだけを検出するという意味ではないので注意が必要です。どういうことかと言うと、isNaN()はNaNになり得る値はすべて「true」判定されるということです。
例えば、以下のサンプル例を見て下さい!
console.log(isNaN(0/0)); console.log(isNaN(NaN)); console.log(isNaN("こんにちは")); console.log(isNaN(undefined));
実行結果
true true true true
「0 / 0」は先ほども試してNaNになることは確認しましたね。
また、「NaN」自体をisNaNの引数に入れても当然ながら結果は「true」になります。ところが、文字列やundefinedを引数に入れても「true」になっているのが実行結果からも分かりますね。これらの値は数値計算に使うと最終的にNaNとなるので「true」になるわけです。
このようなことから、必ずしもNaNを検出する用途に「isNaN()」は利用することができないのです。
「Number.isNaN()」で正確に判定する方法
簡単に「NaN」を検出したい場合にはどうすれば良いでしょうか?
実は、新しいJavaScriptの仕様であるES2015では、Numberオブジェクトに「isNaN()」が追加されています。
これを使って、先ほどと同じコードを実行してみましょう!
console.log(Number.isNaN(0/0)); console.log(Number.isNaN(NaN)); console.log(Number.isNaN("こんにちは")); console.log(Number.isNaN(undefined));
実行結果
true true false false
実行結果に注目してください!
従来の「isNaN()」だとすべてtrue判定でしたが今回は違いますね。
文字列やundefinedなどの値はしっかりとfalse判定されているので、NaNを検出したい場合には最適な方法と言えるでしょう。
ただし、IEなど一部のブラウザは対応していないので、どうしてもと言う場合には以下のような関数を自作するようにしましょう!
function new_isNaN(value) { return typeof value === "number" && value !== value; }
「undefined」「null」の違いについて
JavaScriptには「NaN」のように単独で意味がある値が他にもあります。
例えば、「undefined」「null」という値はどのような意味があるのでしょうか?簡単に言うと、「undefined」は未定義で「null」は空っぽであることを意味しています。
次の簡単なサンプル例を見て下さい!
var item; var sample = null;
変数「item」は値が何も格納されてない、つまり何も定義されてないので「undefined」になります。変数「sample」には値として「null」が定義されているので、この変数の中身は空っぽであることが明示されていますね。
このように現在の状態を現しているので、これらの値を活用すれば条件分岐などで処理を効率化することができます。「undefined / null」を使った有効な活用方法については、次の記事で詳しくまとめているので参考にしてみてください!
まとめ
今回は、JavaScriptにおける「NaN」という特別な値について解説しました。NaNはJavaScriptプログラミングにおいて、出現頻度の高いキーワードなので覚えておいて損はありません。
皆さんもこの記事を通して、NaNについての知識を深めていってくださいね。