JavaScriptの「Number」オブジェクトにおける「Number.isNaN」メソッド:詳細解説と代替方法
JavaScriptの「Number」オブジェクトには、数値かどうかを判定するメソッドが2種類存在します。グローバルな isNaN()
関数と、Number
オブジェクトの静的メソッドである Number.isNaN()
です。
isNaN()
関数
isNaN()
関数は、引数が数値型 NaN
であるかどうかを判定します。しかし、この関数は引数を強制的に数値に変換してしまうという問題があります。そのため、本来 NaN
でない値が NaN
に変換されてしまい、誤った判定をしてしまう可能性があります。
console.log(isNaN("NaN")); // true ※ 本来はfalseのはず
console.log(isNaN(Infinity / Infinity)); // true ※ 本来はfalseのはず
Number.isNaN()
メソッド
一方、Number.isNaN()
メソッドは、引数が数値型 NaN
である かつ 数値型であるかどうかを判定します。つまり、引数が数値型に変換できるものであっても、実際に NaN
でなければ false
を返します。
console.log(Number.isNaN("NaN")); // false
console.log(Number.isNaN(Infinity / Infinity)); // false
使い分け
一般的には、Number.isNaN()
メソッドの方がより安全で正確な判定を行うことができます。isNaN()
関数を使用する場合は、引数が数値型に変換されてしまう可能性があることに注意する必要があります。
- 数値かどうかを判定するには、
typeof
演算子を使用する方法もあります。
console.log(typeof NaN); // "number"
console.log(typeof Infinity); // "number"
console.log(typeof "NaN"); // "string"
isNaN()
関数とNumber.isNaN()
メソッドはいずれも、非同期処理で使用することはできません。
例
以下の例では、Number.isNaN()
メソッドを使用して、さまざまな値が NaN
であるかどうかを判定しています。
const values = [NaN, Infinity, -Infinity, 0, 1, "NaN", "Infinity", true, false, null, undefined];
for (const value of values) {
console.log(`${value} is NaN: ${Number.isNaN(value)}`);
}
このコードを実行すると、以下の出力が得られます。
NaN is NaN: true
Infinity is NaN: false
-Infinity is NaN: false
0 is NaN: false
1 is NaN: false
NaN is NaN: false
Infinity is NaN: false
true is NaN: false
false is NaN: false
null is NaN: false
undefined is NaN: false
const values = [NaN, Infinity, -Infinity, 0, 1, "NaN", "Infinity", true, false, null, undefined];
for (const value of values) {
console.log(`${value} is NaN: ${Number.isNaN(value)}`);
}
NaN is NaN: true
Infinity is NaN: false
-Infinity is NaN: false
0 is NaN: false
1 is NaN: false
NaN is NaN: false
Infinity is NaN: false
true is NaN: false
false is NaN: false
null is NaN: false
undefined is NaN: false
詳細
このコードは以下の通り動作します。
values
という配列に、さまざまな値を代入します。for...of
ループを使用して、values
配列の各要素を反復処理します。- 各要素について、
Number.isNaN()
メソッドを使用してNaN
であるかどうかを判定し、結果をコンソールに出力します。
- データを数値に変換する前に、
NaN
でないことを確認する - 計算結果が
NaN
であるかどうかを判定する - ユーザー入力データが数値かどうかを検証する
JavaScriptの Number.isNaN()
メソッドは、数値かどうかを判定するのに役立ちますが、いくつかの注意点があります。
- 非同期処理で使用できない
- 引数を数値に変換してしまう可能性がある
これらの理由から、状況によっては Number.isNaN()
メソッドの代替方法が必要になる場合があります。
代替方法
以下に、Number.isNaN()
メソッドの代替方法をいくつか紹介します。
x !== x 式
JavaScriptにおいて、x !== x
式は NaN
である場合にのみ true
を返します。これは、Number.isNaN()
メソッドよりも高速で、非同期処理でも使用できます。
function isNaN(x) {
return x !== x;
}
console.log(isNaN(NaN)); // true
console.log(isNaN(Infinity)); // false
console.log(isNaN("NaN")); // false
正規表現
正規表現を使用して、数値形式かどうかを判定することもできます。
function isNaN(x) {
return !/^-?\d+\.?\d*$/.test(x);
}
console.log(isNaN(NaN)); // true
console.log(isNaN(Infinity)); // false
console.log(isNaN("NaN")); // true
自作関数
独自の関数を作成して、NaN
であるかどうかを判定することもできます。
function isNaN(x) {
return typeof x === "number" && isFinite(x);
}
console.log(isNaN(NaN)); // true
console.log(isNaN(Infinity)); // false
console.log(isNaN("NaN")); // false
ライブラリを使用する
lodash
や underscore
などのライブラリには、isNaN
メソッドの代替となるユーティリティ関数などが含まれている場合があります。
const isNaN = require('lodash.isNaN');
console.log(isNaN(NaN)); // true
console.log(isNaN(Infinity)); // false
console.log(isNaN("NaN")); // false
注意点
これらの代替方法を使用する際には、それぞれの特徴と注意点に注意する必要があります。
- ライブラリのユーティリティ関数は使いやすいですが、ライブラリの追加読み込みが必要となります。
- 自作関数は柔軟性がありますが、テストと検証が必要となります。
- 正規表現は比較的精度が高いですが、複雑で読みづらいコードになる場合があります。
x !== x
式は最も高速ですが、精度が低く、NaN
以外の値もtrue
と判定してしまう可能性があります。