質問

簡単な質問があります (そう願っています!)。JS では、なぜ isNaN(" ") false と評価されますが、 isNaN(" x") trueと評価しますか?

テキスト入力フィールドで数値演算を実行し、フィールドが null、""、または NaN であるかどうかを確認しています。誰かがフィールドにいくつかのスペースを入力すると、検証は 3 つすべてで失敗し、なぜ isNAN チェックを通過するのか混乱しています。

ありがとう!

役に立ちましたか?

解決

JavaScriptは空の文字列を0として解釈し、isNANテストに失敗します。空の文字列を0に変換しない文字列に対して最初にparseIntを使用できます。結果はisNANに失敗します。

他のヒント

これは驚くかもしれませんが、多分そうではないかもしれませんが、JavaScriptエンジンの奇抜さを示すためのテストコードを次に示します。

document.write(isNaN("")) // false
document.write(isNaN(" "))  // false
document.write(isNaN(0))  // false
document.write(isNaN(null)) // false
document.write(isNaN(false))  // false
document.write("" == false)  // true
document.write("" == 0)  // true
document.write(" " == 0)  // true
document.write(" " == false)  // true
document.write(0 == false) // true
document.write(" " == "") // false

そのため、

" " == 0 == false

and

"" == 0 == false

しかし

"" != " "

楽しんでください:)

使用してみてください:

alert(isNaN(parseInt("   ")));

または

alert(isNaN(parseFloat("    ")));

Javascriptのタイピングが原因だと思います: '' はゼロに変換されますが、 'x' はそうではありません:

alert(' ' * 1); // 0
alert('x' * 1); // NaN

正確なisNumber関数を実装する場合、Douglas Crockfordによる Javascript:The Good Parts [105ページ]からそれを行う1つの方法を次に示します

var isNumber = function isNumber(value) {
   return typeof value === 'number' && 
   isFinite(value);
}

完全に正解ではない回答

Antonio Haleyの非常に支持され受け入れられた回答は、このプロセスがJavaScriptの parseInt 関数:

  

文字列でparseIntを使用できます...結果はisNANに失敗します。

文字列" 123abc" を使用すると、このステートメントを簡単に反証できます:

parseInt("123abc")    // 123     (a number...
isNaN("123abc")       // true     ...which is not a number)

これにより、JavaScriptの parseInt 関数が数値 123 として" 123abc" を返しますが、その isNaN 関数は、" 123abc" は数字ではないことを示しています。

正解

ECMAScript-262は、isNaN チェックがどのように機能するかを定義します。 >セクション18.2.3

  

18.2.3 isNaN (数値)

     

isNaN 関数は、%isNaN%組み込みオブジェクトです。 isNaN 関数が1つの引数番号で呼び出されると、次の手順が実行されます。

     
      
  1. num にする? ToNumber(number)
  2.   
  3. num NaN の場合、 true を返します。
  4.   
  5. それ以外の場合、 false を返します。
  6.   

参照する ToNumber 関数は、 ECMAScript-でも定義されています。 262のセクション7.1.3 。ここでは、この関数に渡される文字列をJavaScriptがどのように処理するかを説明します。

質問の最初の例は、空白文字のみを含む文字列です。このセクションでは、次のことを説明しています。

  

空または空白のみを含む StringNumericLiteral は、 +0 に変換されます。

"したがって、" サンプル文字列は、数値である +0 に変換されます。

同じセクションにも次のように記載されています:

  

文法が String StringNumericLiteral の拡張として解釈できない場合、 ToNumber の結果は NaN

そのセクションに含まれるすべてのチェックを引用することなく、"質問で示されているx" の例は、 StringNumericLiteral として解釈できないため、上記の条件に該当します。 "したがって、x" NaN に変換されます。

なぜかはわかりませんが、問題を回避するには、チェックする前に常に空白を削除できます。とにかくそれをしたいでしょう。

関数 isNaN("")は、 String to Number type coercion

を実行します

ECMAScript 3-5は、 typeof演算子:

  • 未定義
  • オブジェクト(null、オブジェクト、配列)
  • ブール
  • number
  • string
  • 関数

テストを関数本体にラップする方が良い:

function isNumber (s) {
    return typeof s == 'number'? true
           : typeof s == 'string'? (s.trim() === ''? false : !isNaN(s))
           : (typeof s).match(/object|function/)? false
           : !isNaN(s)
}

この関数は、変数 type をテストするためのものではなく、強制値をテストします。たとえば、ブール値と文字列は数値に強制変換されるため、この関数を isNumberCoerced()

として呼び出すことができます。

string および number 以外の types をテストする必要がない場合、次のスニペットが何らかの条件の一部として使用される可能性があります:

if (!isNaN(s) && s.toString().trim()!='') // 's' can be boolean, number or string
    alert("s is a number")

整数かどうかを適切にチェックする必要がある場合は、次の関数を使用することをお勧めします。

function isInteger(s)
{
   return Math.ceil(s) == Math.floor(s);
}

isNaN("")はfalseです。これは、非数値の数値型への強制により、 isNaN グローバル関数の混乱する動作の一部です。 。

MDN

  

isNaN 関数仕様の最も初期のバージョンなので、非数値引数の動作は混乱を招きました。 isNaN 関数の引数が数値型ではない場合、値は最初に数値に強制変換されます。次に、結果の値をテストして、 NaN であるかどうかを判断します。したがって、数値型に強制されたときに有効な非NaN数値(特に、強制されたときに数値が0または1になる空の文字列およびブールプリミティブ)になる非数値の場合、「false」戻り値は予期しない場合があります。たとえば、空の文字列は必ず「数字ではない」

ECMAScript 6では、 Number.isNaN メソッドもあることに注意してください。MDNによると、

  

グローバルな isNaN()関数と比較して、 Number.isNaN()は、パラメーターを強制的に数値に変換する問題を抱えていません。これは、通常は NaN に変換されるが、実際には NaN と同じ値ではない値を渡すことが安全であることを意味します。これはまた、 NaN である型番号の値のみが true を返すことを意味します。

残念ながら

ECMAScript 6の Number.isNaN メソッドにも、ブログ投稿で説明されているように、独自の問題があります-いJavaScriptとES6 NaNの問題の修正

他で説明したように、 isNaN 関数は空の文字列を検証する前に強制的に数値に変換し、空の文字列を0(有効な数値)に変更します。 ただし、空の文字列またはスペースのみの文字列を解析しようとすると、 parseInt 関数が NaN を返すことがわかりました。そのため、次の組み合わせはうまく機能しているようです:

if(isNaN(string)|| isNaN(parseInt(string)))console.log( 'Not a number!');

このチェックは、正の数値、負の数値、および小数点付きの数値に対して機能するため、すべての一般的な数値のケースをカバーすると考えています。

この関数は私のテストで機能しているように見えました

function isNumber(s) {
    if (s === "" || s === null) {
        return false;
    } else {
        var number = parseInt(s);
        if (number == 'NaN') {
            return false;
        } else {
            return true;
        }
    }
}

はどうですか

function isNumberRegex(value) {        
    var pattern = /^[-+]?\d*\.?\d*$/i;
    var match = value.match(pattern);
    return value.length > 0 && match != null;
}

isNaN 関数は引数として数値を想定しているため、他のタイプの引数(あなたの場合は文字列)は実際の関数ロジックの前に数値に変換されます は発表された。 ( NaN はNumber型の値でもあることに注意してください!)

ところで。これは all 組み込み関数に共通です-特定の型の引数が必要な場合、実際の引数は標準の変換関数を使用して変換されます。すべての基本型(bool、string、number、object、date、null、undefined)の間には標準的な変換があります。

String から Number への標準変換は、 Number()を使用して明示的に呼び出すことができます。そのため、次のことがわかります。

  • Number("") 0 に評価されます
  • Number(" x") NaN
  • と評価されます

これを考えると、 isNaN 関数の結果は完全に論理的です!

実際の問題は、標準の文字列から数値への変換がなぜ機能するのかということです。文字列から数値への変換は、実際には" 123"のような数値文字列を変換することを目的としています。または「17.5e4」同等の数字に。変換では、最初に最初の空白がスキップされるため(" 123"が有効です)、残りは数値として解析されます。数値として解析できない場合(「x」はそうではない)、結果はNaNになります。しかし、空または空白のみの文字列は0に変換されるという明示的な特別なルールがあります。そのため、変換について説明します。

リファレンス: http://www.ecma-international .org / ecma-262 / 5.1 /#sec-9.3.1

この問題を解決するために、このクイック関数を作成しました。

function isNumber(val) {
     return (val != undefined && val != null && val.toString().length > 0 && val.toString().match(/[^0-9\.\-]/g) == null);
};

数値(0-9)ではなく、「-」または「。」ではなく、未定義、ヌル、または空ではない文字をチェックし、一致しない場合はtrueを返します。 :)

JavaScript 内蔵 はNaN この関数は、デフォルトで予想されるとおり、「動的型演算子」です。したがって、(DTCプロセス中に)単純なtrueを生成する可能性のあるすべての値|のような偽 "", " ", " 000", 、NaN にすることはできません。

つまり、 口論 供給されたものは最初に 変換 次のように:

function isNaNDemo(arg){
   var x = new Number(arg).valueOf();
   return x != x;
}

説明:

関数本体の一番上の行では、(最初に) 引数を数値オブジェクトに正常に変換しようとしています。そして (2 番目)、ドット演算子を使用して、私たち自身の便宜上、すぐに削除します。 原生的 価値 作成されたオブジェクトの。

2 行目では、前のステップで取得した値と、次の利点を利用しています。 NaN 宇宙の何とも等しくなく、それ自体とさえも等しくありません。例: NaN == NaN >> false 最後にそれを(不平等について)それ自体と比較します。

このようにして、関数の戻り値は次のようになります。 真実 指定された引数戻り値が数値オブジェクト、つまり非数値への変換に失敗した場合のみ。たとえば、NaN。


isNaNstatic( )

ただし、静的型演算子の場合は、必要に応じて、次のようなはるかに単純な関数を作成できます。

function isNaNstatic(x){   
   return x != x;
}

また、引数が明示的に NaN 数値でない場合は false を返すように、DTC を完全に回避します。したがって、以下に対してテストします。

isNaNStatic(" x"); // will return false それはまだ文字列だからです。

しかし:isNaNStatic(1/"x"); // will of course return true. 例えばそうなるように isNaNStatic(NaN); >> true.

しかし、それに反して isNaN, 、 isNaNStatic("NaN"); >> false それ(引数)は通常の文字列であるためです。

追記:isNaN の静的バージョンは、最新のコーディング シナリオで非常に役立ちます。そしてそれが、私がこれを投稿するのに時間を費やした主な理由の 1 つである可能性があります。

よろしく。

isNAN(< argument>)は、指定された引数が不正な数であるかどうかを判断する関数です。 isNaN は引数をNumber型に型キャストします。引数が数値かどうかを確認したい場合は? jQueryで $。isNumeric()関数を使用してください。

つまり、isNaN(foo)はisNaN(Number(foo))と同等です 明らかな理由により、すべての数字が数字として含まれる文字列を受け入れます。例:

isNaN(123) //false
isNaN(-1.23) //false
isNaN(5-2) //false
isNaN(0) //false
isNaN('123') //false
isNaN('Hello') //true
isNaN('2005/12/12') //true
isNaN('') //false
isNaN(true) //false
isNaN(undefined) //true
isNaN('NaN') //true
isNaN(NaN) //true
isNaN(0 / 0) //true

これを使用

    function isNotANumeric(val) {
    	if(val.trim && val.trim() == "") {
         return true;
      } else {
      	 return isNaN(parseFloat(val * 1));
      }
    }
    
    alert(isNotANumeric("100"));  // false
    alert(isNotANumeric("1a"));   // true
    alert(isNotANumeric(""));     // true
    alert(isNotANumeric("   "));  // true

NaN !==" not a number"

NaN は数値型の値です

これはECMAScriptのisNaN()の定義です

1. Let num be ToNumber(number).
2. ReturnIfAbrupt(num).
3. If num is NaN, return true.
4. Otherwise, return false.

任意の値を数値に変換してみてください。

Number(" ") // 0
Number("x") // NaN
Number(null) // 0

値が NaN であるかどうかを判断する場合は、最初に値を数値に変換する必要があります。

特定の文字列値が空白または"であるかどうかを確認する場合" is isNaN は、文字列検証の実行を試みる場合があります。例:

// value =" 123" if(value.match(/ \ s /)|| isNaN(value)){    //何かをする }

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top