読者です 読者をやめる 読者になる 読者になる

やるしかなっちゃん

やるしかない!

JavaScriptの型判定

typeof

typeofは色々と使いにくいです
特にnew Hoge()したものは'object'になってしまいます

// 正しく判定できるパターン
typeof 1         // 'number'
typeof '1'       // 'string'
typeof true      // 'boolean'
typeof undefined // 'undefined'

// 'object'になってしまうパターン
typeof null            // 'object'
typeof []              // 'object'
typeof new String('1') // 'object'
typeof new Date()      // 'object'

Object.prototype.toString()

typeofが使いにくいのならばどうすれば?と思うかもしれませんが実は素晴らしいメソッドがあるのです
Object.prototype.toString() - JavaScript | MDN
MDNにも記載されている様にオブジェクトクラスの検出にObject.prototype.toString()を使うということができます

Object.prototype.toString.call(1)               // '[object Number]'
Object.prototype.toString.call(null)            // '[object Null]'
Object.prototype.toString.call(undefined)       // '[object Undefined]'
Object.prototype.toString.call([])              // '[object Array]'
Object.prototype.toString.call(new String('1')) // '[object String]'
Object.prototype.toString.call(new Date())      // '[object Date]'

まとめ

以上より型判定を行い時はObject.prototype.toString()を使いましょう
ちなみに↓のようにsliceをしておけば型名だけを取り出せます

Object.prototype.toString.call(1).slice(8, -1) // 'Number'

ここまで書いておいてなんですが、少し不安になったので幾つか調べてみましたがやはり出来る人たちはもう少し丁寧にやってますね
便利関数として自作する場合は↓を参考にして下さい
JavaScriptでオブジェクトの型を判別するのにtypeof演算子使うとツラいよね - Qiita
jQueryはどうやって型判定してるのか - Qiita]

おまけ(NaNの判定)

NaN判定もやりたい時ってありますよね
Object.prototype.toString.call(NaN).slice(8, -1)は実は'Number'になります
なのでisNaNを使うしかないのですが、トップレベルのisNaN関数はあまり厳密ではないです

isNaN(NaN)       // true
isNaN(undefined) // true
isNaN("hoge")    // true

一番最後の例は文字列から数値への変換が失敗してNaNになってしまっています
文字列は数値ではないので(Not a Numberなので)正しいのでは?とも思いますが求めているものとは少し違いますよね
これを回避するためにはNumber.isNaNを使いましょう
Number.isNaNは純粋にNaNであるかどうかを判定できます

Number.isNaN(NaN)       // true
Number.isNaN(undefined) // false
Number.isNaN("hoge")    // false