JavaScriptでtypeofよりも正確に型を判定する方法

JavaScriptで値がどのような型を持つかはtypeofを使えば調べられます。

ですが1つ問題点があってそれは必ずしも正確な型情報を返すわけではないということ

そこでここではtypeofの問題点や代わりになるコードについて紹介します。

typeofは必ずしも正確な型を返さない

まず初めにtypeofの何が問題なのかについて説明しましょう。

それは冒頭でも書いたように必ずしも正確な型を返すとは限らない、ということ

 

「そもそもtypeofって何?」という人もいるかもしれないので説明すると、

値や式に対して typeof 値や式  でそのデータ型を返す構文のことです。

例えば次はtypeofに値や式を渡してコンソールに表示しているコード例

コンソールにはコメント文に書いたような number  とか string  とかの型名が表示されます。

 

ですが問題となるのは次のように配列とかクラスオブジェクトを渡した場合

上のコードだと Array  とか String とか Number  とかが返ってくると思いがち

ですが残念ながら全部 object  で返ってきます。

 

クラスはまだしも、なんで配列までobjectになるの?

と思ってしまいますが、それはtypeofが対応している型を調べれば分かります。

実際MDNのリファレンスを見るとtypeofの返すことができる値の一覧表が載っています。

その一覧表の一部をここにも載せておくと次の通り

戻り値
未定義 "undefined"
Null "object"
真偽値 "boolean"
数値 "number"
文字列 "string"
シンボル "symbol"
関数オブジェクト "function"
他のオブジェクト "object"

一部省略していますが、typeofは基本プリミティブ型を判定するためのものです。

配列にも対応してなく、ましてやStringとかNumberとかのクラス名を返すこともできません。

それらは「他のオブジェクト」に分類されるので全て object  という値が返されるわけです。

 

つまりここまでをまとめると

typeofは基本的な型以外は全てobjectとして返されてしまう

ということ

ではそうすれば具体的な型名を調べられるのか、その方法を次で紹介しましょう。

typeofを使わず具体的な型名を調べる方法

その詳しいコードについては次のStackoverFlowページに載っていました。

 

一番最初の回答のなかにある次のコードです。

このコードを一番最初に書くことでObjectを継承している全てのクラスでgetName関数が使用できるようになります。

 

実際にこのコードを使って配列とかクラスの型名を調べることが可能です。

例えば次は先ほどの配列やクラスを getName  に置き換えたコード例

コメントを見てもらえば分かるようにちゃんとクラス名が返ってきます。

 

一応これがどういう原理でクラス名を取得しているか解説すると次の通り

  1. クラスのコンストラクタ関数にマッチする正規表現を用意
  2. コンストラクタ関数を文字列化してマッチ部分を取得
  3. 正しい結果ならコンストラクタ関数の関数名だけを返す

大まかな仕組みを説明するとこんな感じですかね。

これで今まで取得できなかったクラス名まで取得できるようになりました。

 

もちろんプリミティブな型に対してはtypeofを使った方がいいです。

ですがどうしてもクラス名や配列かどうか調べたい場合にはこちらの方法を使うのがベスト

ここまでのまとめ

ということで簡単にここまでのまとめ

  • typeofは配列やクラスでは使えない
    typeof [1, 2, 3]  とか typeof new Number(10)  とかしても全て object が返ってきてしまう
  • コンストラクタ関数の名前を調べればOK
    なので配列やクラスに限っては getName  などを自作して調べれば取得可能

typeofでは基本的な型以外は名前を取得できないことに注意です。

なのでクラスや配列に対して型名を調べたいときはStackOverflowのようなコードが役立ちます。

ではでは($・・)/~~~