R-SQUARE.net

研究開発部

JavaScript グローバル関数 isNaN の罠

JavaScript で isNaN(undefined) は true なのに isNaN(null) は true にならないことに気づいて、 実行結果のよくわからないJavaScriptグローバル関数をいくつか試してみた。

JavaScriptで、引数で指定された変数が数値かどうかで処理を分岐させようと思ったら、isNaNの結果がワケワカメでめげた。 型キッチリ言語のJavaでは、Exception吐かないようにするために、処理を呼び出す前にアレコレ調べてから実行するのが定石(だと思う)。 でも、型ゆる言語のJavaScriptでは、とりあえず数値変換してからその結果を調べる方が楽かもしれない。型ゆる言語なだけに、関係ない型は抹殺していけってことかな。

数値変換サンプル

JavaScript 定義
/**
 * jsisnan.js
 */
NumUtil = {
  /**
   * 文字列を整数へ変換
   * @param numStr 変換したい文字列
   * @param retVal 変換できなかった場合に返す値
   * @returns 変換結果の整数またはretVal
   */
  toInt:function  (numStr, retVal) {
    if ((typeof numStr == 'string' || typeof numStr == 'number') && !isNaN(parseInt(numStr))) {
      return parseInt(numStr);
    }
    return retVal;
  },
  /**
   * 文字列を数値へ変換
   * @param numStr 変換したい文字列
   * @param retVal 変換できなかった場合に返す値
   * @returns 変換結果の数値またはretVal
   */
  toFloat :function  (numStr, retVal) {
    if ((typeof numStr == 'string' || typeof numStr == 'number') && !isNaN(parseInt(numStr))) {
      return parseFloat(numStr);
    }
    return retVal;
  } 
};
$('#sample_btn').click(function(){
  $('#sample_result').html(
     '<div>NumUtil.toInt("0.21", Number.NaN) => ' + NumUtil.toInt("0.21", Number.NaN) +'</div>' +
     '<div>NumUtil.toInt(null, Number.NaN) => ' + NumUtil.toInt(null, Number.NaN) +'</div>' +
     '<div>NumUtil.toInt(10.3, Number.NaN) => ' + NumUtil.toInt(10.3, Number.NaN) +'</div>' +
     '<div>NumUtil.toInt("", 0) => ' + NumUtil.toInt("", 0) +'</div>' +
     '<div>NumUtil.toInt(["3","9","7"], Number.NaN) => ' + NumUtil.toInt(["3","9","7"], Number.NaN) +'</div>' +
     '<div>NumUtil.toInt("13h", 0) => ' + NumUtil.toInt("13h", 0) +'</div>' +
     '<div>NumUtil.toFloat("0.21", Number.NaN) => ' + NumUtil.toFloat("0.21", Number.NaN) +'</div>' +
     '<div>NumUtil.toFloat(null, -1) => ' + NumUtil.toFloat(null, -1) +'</div>' +
     '<div>NumUtil.toFloat(10.3, Number.NaN) => ' + NumUtil.toFloat(10.3, Number.NaN) +'</div>' +
     '<div>NumUtil.toFloat("", 0) => ' + NumUtil.toFloat("", 0) +'</div>' +
     '<div>NumUtil.toFloat(["3","9","7"], Number.NaN) => ' + NumUtil.toFloat(["3","9","7"], Number.NaN) +'</div>' +
     '<div>NumUtil.toFloat("12.8m", Number.NaN) => ' + NumUtil.toFloat("12.8m", Number.NaN) +'</div>'
  );
});
      


動作例



まとめ

  • JavaScriptで数値変換するときは、isNaNで調べてからparseするのでなく、とりあえずparseしてからisNaNで調べよう。
  • 数字の入った配列はparseできてしまうので、それを避ける場合は、typeofで型を調べてからparseしよう。


参考文献

「JavaScript 第6版」 David Flanagan (著), 村上 列 (翻訳) オライリージャパン (2012/08/15 初版 第1刷) 
「JavaScriptリファレンス 第6版」 David Flanagan (著), 木下 哲也 (翻訳) オライリージャパン (2012/08/15 初版 第1刷) 
last modified : 2017-07-11T22:22:26+09:00