39

一部のプロジェクトでは、一部のデータを検証し、数学演算で使用できる JavaScript の数値であることをできる限り確認する必要がありました。

jQuery、および他のいくつかの JavaScript ライブラリには、通常 isNumeric と呼ばれるそのような関数が既に含まれています。答えとして広く受け入れられているstackoverflowに関する投稿もあります。これは、前述のライブラリが使用しているのと同じ一般的なルーチンです。

function isNumber(n) {
  return !isNaN(parseFloat(n)) && isFinite(n);
}

初めての投稿で、そのスレッドに返信できませんでした。受け入れられた投稿で私が抱えていた問題は、私が行っていたいくつかの作業に影響を与えるいくつかのまれなケースがあるように見えるということでした.

まず、上記のコードは、引数が長さ 1 の配列であり、その単一の要素が上記のロジックによって数値と見なされる型である場合に true を返します。私の意見では、配列の場合は数値ではありません。

この問題を軽減するために、ロジックから配列を割引するチェックを追加しました

function isNumber(n) {
  return Object.prototype.toString.call(n) !== '[object Array]' &&!isNaN(parseFloat(n)) && isFinite(n);
}

もちろん、Array.isArray代わりに使用することもできますObject.prototype.toString.call(n) !== '[object Array]'

編集:$.isArray配列の一般的なテストを反映するようにコードを変更しました。または、jqueryまたはプロトタイプを使用することもできますObject.isArray

私の 2 番目の問題は、負の 16 進数の整数リテラル文字列 ("-0xA" -> -10) が数値としてカウントされていないことでした。ただし、正の 16 進整数リテラル文字列 ("0xA" -> 10) は数値として扱われていました。どちらも有効な数値である必要がありました。

次に、これを考慮してロジックを修正しました。

function isNumber(n) {
  return Object.prototype.toString.call(n) !== '[object Array]' &&!isNaN(parseFloat(n)) && isFinite(n.toString().replace(/^-/, ''));
}

関数が呼び出されるたびに正規表現が作成されることが心配な場合は、次のようにクロージャー内で書き直すことができます。

isNumber = (function () {
  var rx = /^-/;

  return function (n) {
      return Object.prototype.toString.call(n) !== '[object Array]' && !isNaN(parseFloat(n)) && isFinite(n.toString().replace(rx, ''));
  };
}());

次に、CMSの+30 個のテスト ケースを取得し、jsfiddleでのテストを複製して、追加のテスト ケースと上記のソリューションを追加しました。

すべてが期待どおりに機能しているようで、問題は発生していません。コード上または理論上の問題はありますか?

広く受け入れられている/使用されている回答に取って代わるものではないかもしれませんが、これが isNumeric 関数の結果として期待されているものである場合は、これが役立つことを願っています.

EDIT : Bergiが指摘したように、数値と見なされる可能性のあるオブジェクトは他にもあり、ブラックリストよりもホワイトリストに登録することをお勧めします。これを念頭に置いて、私は基準に追加します。

isNumeric 関数で数値または文字列のみを考慮したい

これを念頭に置いて、使用する方が良いでしょう

function isNumber(n) {
  return (Object.prototype.toString.call(n) === '[object Number]' || Object.prototype.toString.call(n) === '[object String]') &&!isNaN(parseFloat(n)) && isFinite(n.toString().replace(/^-/, ''));
}

これはテスト 22 として追加されました

4

7 に答える 7

4

私の意見では、配列の場合は数値ではありません。この問題を軽減するために、ロジックから配列を割引するチェックを追加しました

たとえば、他のオブジェクトでもその問題が発生する可能性があります{toString:function(){return "1.2";}}。どのオブジェクトが数値だと思いますか? Numberオブジェクト?なし?

テストに失敗したものをブラックリストに登録する代わりに、数値にしたいものを明示的にホワイトリストに登録する必要があります。プリミティブ文字列と数値、関数は何を取得することになっていますか? 次に、それらを正確にテストします。

(typeof n == "string" || typeof n == "number")
于 2013-03-05T17:36:38.163 に答える
1

正規表現を使用しても問題ない場合は、次の方法でうまくいく可能性があります。

function (n) 
    { 
    return (Object.prototype.toString.call(n) === '[object Number]' ||
            Object.prototype.toString.call(n) === '[object String]') && 
           (typeof(n) != 'undefined')  &&  (n!=null) && 
           (/^-?\d+((.\d)?\d*(e[-]?\d)?(\d)*)$/.test(n.toString()) ||
           /^-?0x[0-9A-F]+$/.test(n.toString()));
    }

編集: 16進数の問題を修正

于 2013-03-07T13:54:03.520 に答える
0

値が数値かどうかをチェックするために使用される isNaN 関数。値が数値の場合は true を返し、それ以外の場合は false を返します。

コード:

 <script>

         function IsNumeric(val) {

              if (isNaN(parseFloat(val))) {

                 return false;

          }

          return true

  }


  bool IsNumeric(string);


</script>
于 2013-03-09T13:02:52.103 に答える
0
function isNumber(value){
    return !isNaN(parseFloat(value)) && 
        isFinite(value.toString().replace(/^-/, '')) && 
        typeof value !== 'object';

}

また :

function isNumber(value){
    return !Array.isArray(value) && !isNaN(parseFloat(value)) && 
        isFinite(value.toString().replace(/^-/, '')) && 
        Object.prototype.toString.call(value) !== '[object Object]';
}
于 2013-03-10T01:18:29.970 に答える
0

どうですか:

function isNumber(value) {
  value = Number(value);
  return typeof value === 'number' && !isNaN(value) && isFinite(value);
}
于 2013-03-05T00:01:41.090 に答える
0
function isNumber(value){return typeof value == 'number';}
于 2013-02-27T02:02:33.617 に答える
0

AMD がいいと思ったら、mout の isNumber()を見てください。

于 2013-02-27T23:47:32.953 に答える