menu
書いてる野郎
orebike@gmail.com
JS でそれ自体が数値であるかのチェック、つまり数値チェック、数値であるかの判定をしたいことがある場合にどうするかをまとめてみた。
isNaN と typeof の両方の挙動を調べてみた。結論から言うと isNaN は使うな typeof を使え。
isNaNって関数がある。isNaNは「数値ではない」だと真を返す関数(否定形なので紛らわしい)。その挙動のチェックしてみたのでまとめとく。 Firefox2とIE6でやったけどあんまり他でも変わらないでしょこの辺は
まとめると、変な挙動するからこれだけ使わんほうがいいかも
関数 | 状況 | コード | 数値である(関数の結果) | 数値である(人間の期待) | memo |
---|---|---|---|---|---|
isNaN | 数字じゃない文字列 | isNaN('abc'); | false(結果 true) | false | OK 当然の挙動 |
isNaN | 無 | isNaN(); | false(結果 true) | false | OK 当然の挙動 |
isNaN | null | isNaN(null); | true(結果 false) | false | 注意が必要な挙動 |
isNaN | 空の変数(undefined) | isNaN(undefined); | false(結果 true) | false | OK だが null と挙動が合ってない |
isNaN | 空文字 | isNaN(""); | true(結果 false) | false | 注意が必要な挙動、空文字が数値ってどういうことよ |
isNaN | 10進数の数値 | isNaN(123); | true(結果 false) | true | OK 当然の挙動 |
isNaN | 10進数の数値っぽい文字列 | isNaN("123"); | true(結果 false) | false | 注意が必要な挙動。内部で数値に変換されてしまうらしい |
isNaN | 8進数の数値 | isNaN(0123); | true(結果 false) | true | OK 当然の挙動 |
isNaN | 8進数の数値っぽい文字列 | isNaN("0123"); | true(結果 false) | false | 注意が必要な挙動。内部で数値に変換されてしまうらしい |
isNaN | 16進数の数値 | isNaN(0x123); | true(結果 false) | true | OK 当然の挙動 |
isNaN | 16進数の数値っぽい文字列 | isNaN("0x123"); | true(結果 false) | false | 注意が必要な挙動。内部で数値に変換されてしまうらしい |
isNaN | 真偽値(boolean true) | isNaN(true); | true(結果 false) | false | 注意が必要な挙動。内部で数値に変換されてしまうらしい |
isNaN | 真偽値(boolean false) | isNaN(false); | true(結果 false) | false | 注意が必要な挙動。内部で数値に変換されてしまうらしい |
isNaN | 空配列(Array) | isNaN([]); | true(結果 false) | false | 注意が必要な挙動。 |
isNaN | 空配列っぽい文字列 | isNaN("[]"); | false(結果 true) | false | OK 当然の挙動 |
isNaN | 数値が入った配列(Array) | isNaN([12,34]); | false(結果 true) | false | OK だが空配列と挙動が合ってない |
isNaN | 数値っぽい文字列が入った配列(Array) | isNaN(["12","34"]); | false(結果 true) | false | OK だが空配列と挙動が合ってない |
isNaN | 空連想配列(オブジェクト) | isNaN({}); | false(結果 true) | false | OK 当然の挙動 |
MDN に typeof を使えと書いてあったのでこっちも調べてみる。typeof は数値と判定されると「number」という文字列を返すことになっている。 実は typeof は関数ではなく演算子なのだ。
関数 | 状況 | コード | 数値である(関数の結果) | 数値である(人間の期待) | memo |
---|---|---|---|---|---|
typeof | 数字じゃない文字列 | typeof 'abc'; | false(結果“string”) | false | OK 当然の挙動 |
typeof | 無 | typeof(); | false(結果Syntaxエラー) | false | OK というか空の括弧が文法上エラーなのでそもそもこのように書けない |
typeof | null | typeof null; | false(結果“object”) | false | OK 当然の挙動 |
typeof | 空の変数(undefined) | typeof undefined; | false(結果“undefined”) | false | OK 当然の挙動 |
typeof | 空文字 | typeof ""; | false(結果“string”) | false | OK 当然の挙動 |
typeof | 空白文字 | typeof " "; | false(結果“string”) | false | OK 当然の挙動 |
typeof | 10進数の数値 | typeof 123; | true(結果“number”) | true | OK 当然の挙動 |
typeof | 10進数の数値っぽい文字列 | typeof "123"; | false(結果“string”) | false | OK 当然の挙動 |
typeof | 8進数の数値 | typeof 0123; | true(結果“number”) | true | OK 当然の挙動 |
typeof | 8進数の数値っぽい文字列 | typeof "0123"; | false(結果“string”) | false | OK 当然の挙動 |
typeof | 16進数の数値 | typeof 0x123; | true(結果“number”) | true | OK 当然の挙動 |
typeof | 16進数の数値っぽい文字列 | typeof "0x123"; | false(結果“string”) | false | OK 当然の挙動 |
typeof | 真偽値(boolean true) | typeof true; | false(結果“boolean”) | false | OK 当然の挙動 |
typeof | 真偽値(boolean false) | typeof false; | false(結果“boolean”) | false | OK 当然の挙動 |
typeof | 空配列(Array) | typeof []; | false(結果“object”) | false | OK 当然の挙動 |
typeof | 空配列っぽい文字列 | typeof "[]"; | false(結果“string”) | false | OK 当然の挙動 |
typeof | 数値が入った配列(Array) | typeof [12,34]; | false(結果“object”) | false | OK 当然の挙動 |
typeof | 数値っぽい文字列が入った配列(Array) | typeof ["12","34"]; | false(結果“object”) | false | OK 当然の挙動 |
typeof | 空連想配列(オブジェクト) | typeof {}; | false(結果“object”) | false | OK 当然の挙動 |
ということで typeof hogehoge === “number”
で判定すると問題なさげ。