なぜ今、isFiniteの使い分けが重要なのか
JavaScriptで開発をしていると、APIから受け取った値やユーザーの入力値が「正しい数値かどうか」を判定する場面に頻繁に出くわします。もし判定を誤ると、計算結果がInfinity(無限大)になったり、予期せぬエラーを引き起こしたりします。実はJavaScriptには「isFinite」という関数が2種類存在し、その違いを理解していないとバグの温床になります。本記事では、安全な数値判定を行うためのベストプラクティスを解説します。
基礎知識:2つのisFiniteの違い
JavaScriptには、グローバルな「isFinite」と、ES6から導入された「Number.isFinite」があります。
グローバルなisFinite関数は、引数を一度数値に変換(型強制)してから判定します。そのため、文字列の「123」や、ブール値の「true(1として評価される)」を渡すと、trueを返してしまいます。
一方で、Number.isFiniteメソッドは、型変換を行いません。引数が「数値型(Number)」であり、かつ「有限数である」場合にのみtrueを返します。現代のフロントエンド開発では、意図しない型変換を防ぐため、後者の利用が強く推奨されています。
実装と解決策
安全なアプリケーションを構築するために、常にNumber.isFiniteを使用するようにしましょう。これにより、数値以外のデータ型が混入した際に、即座にfalseを返すことができ、バグを未然に防げます。
サンプルプログラム
以下のコードをブラウザのコンソールなどで実行し、挙動の違いを確認してみてください。
// 比較用のテストデータ
const inputs = [123, "123", Infinity, null, undefined, NaN];
console.log("--- Number.isFinite の挙動 ---");
inputs.forEach(val => {
// Number.isFiniteは「型」と「値」の両方を厳密にチェックします
const result = Number.isFinite(val);
console.log(`${val} は有限数か?: ${result}`);
});
console.log("\n--- グローバル isFinite の挙動 ---");
inputs.forEach(val => {
// グローバルなisFiniteは文字列を数値に変換して判定するため注意が必要
const result = isFinite(val);
console.log(`${val} は有限数か?: ${result}`);
});
応用・注意点:現場で陥りやすい罠
現場で最も注意すべき点は、APIから取得した数値が「文字列」として送られてくるケースです。
例えば、`Number.isFinite(“100”)` はfalseを返します。もしAPIのレスポンスをそのまま判定に使ってしまうと、正しい数値であっても弾かれてしまう可能性があります。
解決策としては、判定の前に `const num = Number(value);` のように明示的に数値へ変換してから、`Number.isFinite(num)` でチェックを行うという「変換→判定」のフローを徹底しましょう。
また、`NaN`(非数)はどちらの関数でもfalseになるため、数値の妥当性チェックとして非常に優秀です。これらの特性を理解し、より堅牢なフロントエンドコードを書いていきましょう。