web-dev-qa-db-fra.com

Comment vérifiez-vous qu'un nombre est NaN en JavaScript?

Je n’ai essayé que dans la console JavaScript de Firefox, mais aucune des déclarations suivantes ne renvoie true:

parseFloat('geoff') == NaN;

parseFloat('geoff') == Number.NaN;
350
Paul D. Waite

Essayez ce code:

isNaN(parseFloat("geoff"))

Pour vérifier si la valeur de any est NaN au lieu de simples chiffres, voir ici: Comment testez-vous NaN en Javascript?

501
chiborg

Je viens de rencontrer cette technique dans le livre Effective JavaScript c'est assez simple:

NaN étant la seule valeur JavaScript traitée de manière inégale, vous pouvez toujours vérifier si une valeur est NaN en la vérifiant pour son égalité:

var a = NaN;
a !== a; // true 

var b = "foo";
b !== b; // false 

var c = undefined; 
c !== c; // false

var d = {};
d !== d; // false

var e = { valueOf: "foo" }; 
e !== e; // false

Je ne m'en rendais pas compte avant de commenter @allsyed, mais cela figure dans les spécifications de l'ECMA: https://tc39.github.io/ecma262/#sec-isnan-number

127
Jazzy

Utilisez ce code:

isNaN('geoff');

Voir isNaN() docs on MDN .

alert ( isNaN('abcd'));  // alerts true
alert ( isNaN('2.0'));  // alerts false
alert ( isNaN(2.0));  // alerts false
47
rahul

Dans la mesure où une valeur de type Nombre doit être testée pour savoir si c'est un NaN ou non, la fonction globale isNaN fera le travail.

isNaN(any-Number);

Pour une approche générique qui fonctionne pour tous les types dans JS, nous pouvons utiliser l'un des éléments suivants:

Pour les utilisateurs ECMAScript-5: 

#1
if(x !== x) {
    console.info('x is NaN.');
}
else {
    console.info('x is NOT a NaN.');
}

Pour les personnes utilisant ECMAScript-6:

#2
Number.isNaN(x);

Et par souci de cohérence entre ECMAScript 5 et 6, nous pouvons également utiliser this polyfill pour Number.isNan

#3
//Polyfill from MDN
Number.isNaN = Number.isNaN || function(value) {
    return typeof value === "number" && isNaN(value);
}
// Or
Number.isNaN = Number.isNaN || function(value) {     
    return value !== value;
}

s'il vous plaît vérifier Cette réponse pour plus de détails.

38
dopeddude

NaN est une valeur spéciale qui ne peut pas être testée comme ça. Une chose intéressante que je voulais juste partager est la suivante:

var nanValue = NaN;
if(nanValue !== nanValue) // Returns true!
    alert('nanValue is NaN');

Cela retourne vrai seulement pour les valeurs de NaN et constitue un moyen de test sûr. Devrait définitivement être encapsulé dans une fonction ou au moins commentée, car cela n’a évidemment aucun sens de vérifier si la même variable n’est pas égale, hehe.

16
Jonathan Azulay

Vous devez utiliser l'appel de fonction global isNaN(value), car:

  • Il est supporté par plusieurs navigateurs
  • Voir isNaN pour la documentation

Exemples:

 isNaN('geoff'); // true
 isNaN('3'); // false

J'espère que cela t'aidera.

14
Jerome WAGNER

À partir de ES6 , Object.is(..) est un nouvel utilitaire permettant de tester deux valeurs d'égalité absolue:

var a = 3 / 'bar';
Object.is(a, NaN); // true
12
zangw

Pour résoudre le problème où '1.2geoff' est analysé, utilisez plutôt l'analyseur Number().

Donc plutôt que cela:

parseFloat('1.2geoff'); // => 1.2
isNaN(parseFloat('1.2geoff')); // => false
isNaN(parseFloat('.2geoff')); // => false
isNaN(parseFloat('geoff')); // => true

Faire ceci:

Number('1.2geoff'); // => NaN
isNaN(Number('1.2geoff')); // => true
isNaN(Number('.2geoff')); // => true
isNaN(Number('geoff')); // => true

EDIT: Je viens de remarquer un autre problème à ce sujet cependant ... les fausses valeurs (et true en tant que vrai booléen) sont passées dans Number() et retournent sous forme de 0! Dans ce cas, parseFloat fonctionne chaque fois à la place. Alors retombons à cela:

function definitelyNaN (val) {
    return isNaN(val && val !== true ? Number(val) : parseFloat(val));
}

Et cela couvre apparemment tout. Je l'ai évalué à 90% moins vite que le _.isNaN de lodash mais celui-ci ne couvre pas tous les NaN:

http://jsperf.com/own-isnan-vs-underscore-lodash-isnan

Soyons clairs: le mien s’occupe de l’interprétation littérale humaine de quelque chose qui n’est pas "un nombre" et celui de lodash s’occupe de l’interprétation littérale par ordinateur consistant à vérifier si quelque chose est "NaN".

8
marksyzm

Bien que la réponse de @chiborg IS soit correcte, il y a autre chose à noter:

parseFloat('1.2geoff'); // => 1.2
isNaN(parseFloat('1.2geoff')); // => false
isNaN(parseFloat('.2geoff')); // => false
isNaN(parseFloat('geoff')); // => true

Le fait est que si vous utilisez cette méthode pour valider une entrée, le résultat sera plutôt libéral.

Donc, oui, vous pouvez utiliser parseFloat(string) (ou dans le cas de nombres entiers parseInt(string, radix) 'et ensuite l'envelopper avec isNaN(), mais soyez conscient du piège avec des nombres entrelacés avec des caractères non numériques supplémentaires.

7
Ryan Griffith

Solution simple!

VRAIMENT super simple! Ici! Avoir cette méthode!

function isReallyNaN(a) { return a !== a; };

Utilisez aussi simple que:

if (!isReallyNaN(value)) { return doingStuff; }

Voir test de performance here en utilisant cette fonction vs selected answer

Aussi: Voir ci-dessous le premier exemple pour quelques implémentations alternatives.


Exemple:

function isReallyNaN(a) { return a !== a; };

var example = {
    'NaN': NaN,
    'an empty Objet': {},
    'a parse to NaN': parseFloat('$5.32'),
    'a non-empty Objet': { a: 1, b: 2 },
    'an empty Array': [],
    'a semi-passed parse': parseInt('5a5'),
    'a non-empty Array': [ 'a', 'b', 'c' ],
    'Math to NaN': Math.log(-1),
    'an undefined object': undefined
  }

for (x in example) {
    var answer = isReallyNaN(example[x]),
        strAnswer = answer.toString();
    $("table").append($("<tr />", { "class": strAnswer }).append($("<th />", {
        html: x
    }), $("<td />", {
        html: strAnswer
    })))
};
table { border-collapse: collapse; }
th, td { border: 1px solid; padding: 2px 5px; }
.true { color: red; }
.false { color: green; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<table></table>

Si vous ne souhaitez pas utiliser une méthode nommée alternativement et souhaitez vous assurer qu'elle est disponible de manière plus globale, vous pouvez emprunter deux chemins alternatifs. Avertissement Ces solutions impliquent de modifier des objets natifs et peuvent ne pas être votre meilleure solution. Soyez toujours prudent et gardez à l'esprit que les autres bibliothèques que vous pourriez utiliser peuvent dépendre de code natif ou de modifications similaires.

Autre implémentation 1: Remplacez la méthode native isNaN.

//  Extremely simple. Just simply write the method.
window.isNaN = function(a) { return a !==a; }

Autre implémentation 2: objet Ajouter au nombre
* Recommandé, car il s'agit également d'un poly-fill pour les ECMA 5 à 6

Number['isNaN'] || (Number.isNaN = function(a) { return a !== a });
//  Use as simple as
Number.isNaN(NaN)

Solution alternative test si vide

Une méthode de fenêtre simple que j'ai écrite ce test si l'objet est Vide . C'est un peu différent en ce sens que cela ne donne pas si item est "exactement" NaN , mais je me suis dit que je lancerais ça car ça pourrait aussi être utile lorsqu'on cherche vide articles.

/** isEmpty(varried)
 *  Simple method for testing if item is "empty"
 **/
;(function() {
   function isEmpty(a) { return (!a || 0 >= a) || ("object" == typeof a && /\{\}|\[(null(,)*)*\]/.test(JSON.stringify(a))); };
   window.hasOwnProperty("empty")||(window.empty=isEmpty);
})();

Exemple:

;(function() {
   function isEmpty(a) { return !a || void 0 === a || a !== a || 0 >= a || "object" == typeof a && /\{\}|\[(null(,)*)*\]/.test(JSON.stringify(a)); };
   window.hasOwnProperty("empty")||(window.empty=isEmpty);
})();

var example = {
    'NaN': NaN,
    'an empty Objet': {},
    'a parse to NaN': parseFloat('$5.32'),
    'a non-empty Objet': { a: 1, b: 2 },
    'an empty Array': new Array(),
    'an empty Array w/ 9 len': new Array(9),
    'a semi-passed parse': parseInt('5a5'),
    'a non-empty Array': [ 'a', 'b', 'c' ],
    'Math to NaN': Math.log(-1),
    'an undefined object': undefined
  }

for (x in example) {
        var answer = empty(example[x]),
                strAnswer = answer.toString();
        $("#t1").append(
                $("<tr />", { "class": strAnswer }).append(
                        $("<th />", { html: x }),
                        $("<td />", { html: strAnswer.toUpperCase() })
                )
        )
};


function isReallyNaN(a) { return a !== a; };
for(x in example){var answer=isReallyNaN(example[x]),strAnswer=answer.toString();$("#t2").append($("<tr />",{"class":strAnswer}).append($("<th />",{html:x}),$("<td />",{html:strAnswer.toUpperCase()})))};
table { border-collapse: collapse; float: left; }
th, td { border: 1px solid; padding: 2px 5px; }
.true { color: red; }
.false { color: green; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<table id="t1"><thead><tr><th colspan="2">isEmpty()</th></tr></thead><thead><tr><th>Value Type</th><th>Bool Return</th></tr></thead></table>
<table id="t2"><thead><tr><th colspan="2">isReallyNaN()</th></tr></thead><thead><tr><th>Value Type</th><th>Bool Return</th></tr></thead></table>

Vérification extrêmement profonde si elle est vide

Ce dernier va un peu plus loin, vérifiant même si un objet est plein d'objets vides. Je suis sûr qu'il y a place à amélioration et qu'il y a des pièges, mais jusqu'à présent, il semble attraper presque tout.

function isEmpty(a) {
        if (!a || 0 >= a) return !0;
        if ("object" == typeof a) {
                var b = JSON.stringify(a).replace(/"[^"]*":(0|"0*"|false|null|\{\}|\[(null(,)?)*\]),?/g, '').replace(/"[^"]*":\{\},?/g, '');
                if ( /^$|\{\}|\[\]/.test(b) ) return !0;
                else if (a instanceof Array)  {
                        b = b.replace(/(0|"0*"|false|null|\{\}|\[(null(,)?)*\]),?/g, '');
                        if ( /^$|\{\}|\[\]/.test(b) ) return !0;
                }
        }
        return false;
}
window.hasOwnProperty("empty")||(window.empty=isEmpty);

var example = {
    'NaN': NaN,
    'an empty Objet': {},
    'a parse to NaN': parseFloat('$5.32'),
    'a non-empty Objet': { a: 1, b: 2 },
    'an empty Array': new Array(),
    'an empty Array w/ 9 len': new Array(9),
    'a semi-passed parse': parseInt('5a5'),
    'a non-empty Array': [ 'a', 'b', 'c' ],
    'Math to NaN': Math.log(-1),
    'an undefined object': undefined,
    'Object Full of Empty Items': { 1: '', 2: [], 3: {}, 4: false, 5:new Array(3), 6: NaN, 7: null, 8: void 0, 9: 0, 10: '0', 11: { 6: NaN, 7: null, 8: void 0 } },
    'Array Full of Empty Items': ["",[],{},false,[null,null,null],null,null,null,0,"0",{"6":null,"7":null}]
  }

for (x in example) {
        var answer = empty(example[x]),
                strAnswer = answer.toString();
        $("#t1").append(
                $("<tr />", { "class": strAnswer }).append(
                        $("<th />", { html: x }),
                        $("<td />", { html: strAnswer.toUpperCase() })
                )
        )
};


function isReallyNaN(a) { return a !== a; };
for(x in example){var answer=isReallyNaN(example[x]),strAnswer=answer.toString();$("#t2").append($("<tr />",{"class":strAnswer}).append($("<th />",{html:x}),$("<td />",{html:strAnswer.toUpperCase()})))};
table { border-collapse: collapse; float: left; }
th, td { border: 1px solid; padding: 2px 5px; }
.true { color: red; }
.false { color: green; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<table id="t1"><thead><tr><th colspan="2">isEmpty()</th></tr></thead><thead><tr><th>Value Type</th><th>Bool Return</th></tr></thead></table>
<table id="t2"><thead><tr><th colspan="2">isReallyNaN()</th></tr></thead><thead><tr><th>Value Type</th><th>Bool Return</th></tr></thead></table>
6
SpYk3HH

Si votre environnement prend en charge ECMAScript 2015, vous pouvez utiliser Number.isNaN pour vous assurer que la valeur est réellement NaN.

Le problème avec isNaN est, si vous utilisez cela avec des données non numériques, peu de règles prêtant à confusion (selon MDN) sont appliquées. Par exemple,

isNaN(NaN);       // true
isNaN(undefined); // true
isNaN({});        // true

Ainsi, dans les environnements pris en charge par ECMA Script 2015, vous pouvez utiliser 

Number.isNaN(parseFloat('geoff'))
5
thefourtheye

J'utilise underscore isNaN fonction car en JavaScript:

isNaN(undefined) 
-> true

À tout le moins, soyez conscient de cela.

4
d2vid

NaN en JavaScript signifie "Pas un nombre", bien que son type soit en réalité un nombre.

typeof(NaN) // "number"

Pour vérifier si une variable a la valeur NaN, nous ne pouvons pas simplement utiliser la fonction isNaN (), car isNaN () présente le problème suivant, voir ci-dessous:

var myVar = "A";
isNaN(myVar) // true, although "A" is not really of value NaN

Ce qui se passe réellement ici est que myVar est implicitement contraint à un certain nombre:

var myVar = "A";
isNaN(Number(myVar)) // true. Number(myVar) is NaN here in fact

Cela a du sens, car "A" n’est pas un nombre. Mais ce que nous voulons vraiment vérifier, c'est si myVar a exactement la valeur NaN.

Donc, isNaN () ne peut pas aider. Alors que devrions-nous faire à la place?

À la lumière que NaN est la seule valeur JavaScript traitée de manière inégale, nous pouvons donc vérifier son égalité avec lui-même en utilisant! ==

var myVar; // undefined
myVar !== myVar // false

var myVar = "A";
myVar !== myVar // false

var myVar = NaN
myVar !== myVar // true

Donc pour conclure , s'il est vrai qu'une variable! == elle-même, cette variable est exactement de valeur NaN:

function isOfValueNaN(v) {
    return v !== v;
}

var myVar = "A";
isNaN(myVar); // true
isOfValueNaN(myVar); // false
4
Yuci

function isNotANumber(n) {
  if (typeof n !== 'number') {
    return true;
  } 
  return n !== n;
}

3
Vivek Munde

Il semble que isNaN () ne soit pas pris en charge dans Node.js.
J'ai travaillé avec 

var value = 1;
if (parseFloat(stringValue)+"" !== "NaN") value = parseFloat(stringValue);
3
Stephan Ahlf

Je veux juste partager une autre alternative, ce n'est pas nécessairement meilleur que les autres ici, mais je pense que ça vaut la peine de regarder:

function customIsNaN(x) { return (typeof x == 'number' && x != 0 && !x); }

La logique derrière ceci est que tous les nombres sauf 0 et NaN sont convertis en true.

J'ai fait un test rapide et il fonctionne aussi bien que Number.isNaN et vérifie lui-même la présence de faux. Tous les trois fonctionnent mieux que isNan

Les resultats

customIsNaN(NaN);            // true
customIsNaN(0/0);            // true
customIsNaN(+new Date('?')); // true

customIsNaN(0);          // false
customIsNaN(false);      // false
customIsNaN(null);       // false
customIsNaN(undefined);  // false
customIsNaN({});         // false
customIsNaN('');         // false

Peut devenir utile si vous voulez éviter la fonction isNaN cassée.

3
Tiborg

Le moyen exact de vérifier est:

//takes care of boolen, undefined and empty

isNaN(x) || typeof(x) ==='boolean' || typeof(x) !=='undefined' || x!=='' ? 'is really a nan' : 'is a number'
2
Nishanth Matha
NaN === NaN;        // false
Number.NaN === NaN; // false
isNaN(NaN);         // true
isNaN(Number.NaN);  // true

L'opérateur d'égalité (== et ===) ne peut pas être utilisé pour tester une valeur par rapport à NaN.

Regardez Documentation Mozilla La propriété globale NaN est une valeur représentant Not-A-Numbe

Le meilleur moyen est d'utiliser 'isNaN ()', qui est une fonction intégrée permettant de vérifier NaN. Tous les navigateurs supporte le chemin ..

2
MURATSPLAT

Peut-être aussi ceci:

function isNaNCustom(value){
    return value.toString() === 'NaN' && 
           typeof value !== 'string' && 
           typeof value === 'number'
}
2
Pierfrancesco

la réponse de marksyzm fonctionne bien, mais elle ne renvoie pas false pour Infinity car Infinity n’est techniquement pas un nombre.

je suis venu avec une fonction isNumber qui va vérifier si c'est un nombre.

function isNumber(i) {
    return !isNaN(i && i !== true ? Number(i) : parseFloat(i)) && [Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY].indexOf(i) === -1;
}

console.log(isNumber(Infinity));
console.log(isNumber("asdf"));
console.log(isNumber(1.4));
console.log(isNumber(NaN));
console.log(isNumber(Number.MAX_VALUE));
console.log(isNumber("1.68"));

UPDATE: J'ai remarqué que ce code échouait pour certains paramètres, je l'ai donc amélioré.

function isNumber(i) {//function for checking if parameter is number
if(!arguments.length) {
throw new SyntaxError("not enough arguments.");
	} else if(arguments.length > 1) {
throw new SyntaxError("too many arguments.");
	} else if([Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY].indexOf(i) !== -1) {
throw new RangeError("number cannot be \xB1infinity.");
	} else if(typeof i === "object" && !(i instanceof RegExp) && !(i instanceof Number) && !(i === null)) {
throw new TypeError("parameter cannot be object/array.");
	} else if(i instanceof RegExp) {
throw new TypeError("parameter cannot be RegExp.");
	} else if(i == null || i === undefined) {
throw new ReferenceError("parameter is null or undefined.");
	} else {
return !isNaN(i && i !== true ? Number(i) : parseFloat(i)) && (i === i);
	}
}
console.log(isNumber(Infinity));
console.log(isNumber(this));
console.log(isNumber(/./ig));
console.log(isNumber(null));

1
adddff
alert("1234567890.".indexOf(String.fromCharCode(mycharacter))>-1);

Ce n'est pas élégant. mais après avoir essayé isNAN (), je suis arrivé à cette solution, qui est une autre alternative. Dans cet exemple, j'ai également autorisé "." parce que je me masque pour float. Vous pouvez également inverser cette procédure pour vous assurer qu'aucun nombre n'est utilisé. 

("1234567890".indexOf(String.fromCharCode(mycharacter))==-1)

Il s’agit d’une évaluation à caractère unique, mais vous pouvez également parcourir une chaîne pour rechercher des nombres.

1
Peter S McIntyre

Est-ce que (NaN> = 0) ? ...... " Je ne sais pas ".

function IsNotNumber( i ){
    if( i >= 0 ){ return false; }
    if( i <= 0 ){ return false; }
    return true;
}

Les conditions ne sont exécutées que siTRUE.

Pas surFAUX.

Pas sur " Je ne sais pas ".

1
J.M.I. MADISON

J'ai trouvé un autre moyen, juste pour le plaisir.

function IsActuallyNaN(obj) {
  return [obj].includes(NaN);  
}
1
Madhukar Kedlaya

J'ai écrit cette réponse à une autre question sur StackOverflow où un autre vérifie quand NaN == null mais ensuite, il a été marqué comme étant en double, je ne veux donc pas perdre mon travail.

Regardez Réseau de développeurs Mozilla à propos de NaN.


Réponse courte

Utilisez simplement distance || 0 lorsque vous voulez être sûr que votre valeur correspond à un nombre correct ou à isNaN() pour la vérifier.

Longue réponse

Le NaN (Not-a-Number) est un objet global bizarre en javascript renvoyé fréquemment en cas d'échec d'une opération mathématique.

Vous vouliez vérifier si NaN == null qui résultait false. Hovewer même NaN == NaN résultats avec false.

Un moyen simple de savoir si la variable est NaN est une fonction globale isNaN().

Un autre est x !== x qui n'est vrai que lorsque x est NaN. (merci de rappeler à @ raphael-schweikert)

Mais pourquoi la réponse courte a fonctionné?

Découvrons-le.

Lorsque vous appelez NaN == false, le résultat est false, identique à NaN == true.

Quelque part dans les spécifications, JavaScript a un enregistrement avec toujours des valeurs fausses, qui incluent:

  • NaN - Pas un nombre
  • "" - chaîne vide
  • false - un booléen faux
  • null - objet null
  • undefined - variables non définies
  • 0 - 0 numérique, y compris +0 et -0
1
Roomy

Selon IEEE 754, toutes les relations impliquant NaN sont considérées comme fausses, à l'exception de! =. Ainsi, par exemple, (A> = B) = faux et (A <= B) = faux si A ou B ou les deux est/sont NaN.

1
Ronald Davis

La règle est la suivante:

NaN != NaN

Le problème de la fonction isNaN () est qu’elle peut renvoyer un résultat inattendu dans certains cas:

isNaN('Hello')      //true
isNaN('2005/12/12') //true
isNaN(undefined)    //true
isNaN('NaN')        //true
isNaN(NaN)          //true
isNaN(0 / 0)        //true

Un meilleur moyen de vérifier si la valeur est vraiment NaN est:

function is_nan(value) {
    return value != value
}

is_nan(parseFloat("geoff"))
1
Bob Slave

Une autre solution est mentionnée dans La page parseFloat de MDN

Il fournit une fonction de filtre pour effectuer une analyse syntaxique stricte

var filterFloat = function (value) {
    if(/^(\-|\+)?([0-9]+(\.[0-9]+)?|Infinity)$/
      .test(value))
      return Number(value);
  return NaN;
}


console.log(filterFloat('421'));               // 421
console.log(filterFloat('-421'));              // -421
console.log(filterFloat('+421'));              // 421
console.log(filterFloat('Infinity'));          // Infinity
console.log(filterFloat('1.61803398875'));     // 1.61803398875
console.log(filterFloat('421e+0'));            // NaN
console.log(filterFloat('421hop'));            // NaN
console.log(filterFloat('hop1.61803398875'));  // NaN

Et puis vous pouvez utiliser isNaN pour vérifier si c'est NaN

1
Zzy

J'ai créé cette petite fonction qui fonctionne à merveille ... Au lieu de rechercher NaN qui semble être contre-intuitif, vous recherchez un numéro. Je suis presque sûr que je ne suis pas le premier à le faire de cette façon, mais je pensais partager.

function isNum(val){
    var absVal = Math.abs(val);
    var retval = false;
    if((absVal-absVal) == 0){
        retval = true
    }

    return retval;
}
1
Billy Hallman

Convertissez simplement le résultat en String et comparez-le avec 'NaN'.

var val = Number("test");
if(String(val) === 'NaN') {
   console.log("true");
}
0
Manikandan Arun