162 votes

Pourquoi est-isNaN(null) == false en JS?

Ce code en JS me donne une fenêtre en disant: "je pense que null est un nombre", que je trouve un peu inquiétant. Ce qui me manque?

if (isNaN(null)) {
  alert("null is not a number");
} else {
  alert("i think null is a number");
}

Je suis de l'utilisation de Firefox 3. C'est qu'un navigateur bug?

D'autres tests:

null == NaN; // false
isNaN("text"); // true
NaN == "text" // false

Donc, le problème ne semble pas être une comparaison exacte avec NaN?

Edit: Maintenant, la question a été posée, j'ai nettoyé mon post pour avoir une meilleure version de l'archive. Cependant, ce qui rend certains des commentaires et même quelques réponses un peu incompréhensible. Ne blâme pas leurs auteurs. Parmi les choses que j'ai changé, c'est:

  • Retiré une note disant que j'avais foiré le titre, en premier lieu, en revenant de son sens
  • Les réponses précédentes ont montré que je n'ai pas d'état assez clairement pourquoi j'ai pensé que le comportement était bizarre, j'ai donc ajouté les exemples que l'enregistrement d'une chaîne et de faire une comparaison manuelle.

135voto

Glenn Moss Points 2363

Je crois que le code est d'essayer de demander, "est - x numérique?" avec le cas particulier ici d' x = null. La fonction isNaN() peut être utilisée pour répondre à cette question, mais du point de vue sémantique, c'est en se référant à la valeur NaN. À partir de Wikipédia, NaN:

NaN (Not un Nombre) est une valeur du type de données numériques représentant un indéfini ou irreprésentable de la valeur, en particulier dans les calculs en virgule flottante.

Dans la plupart des cas, nous pensons que la réponse à "est null numérique?" devrait être non. Toutefois, isNaN(null) == false est sémantiquement correct, car null n'est NaN.

Voici l'algorithmique explication:

La fonction isNaN(x) tente de convertir le paramètre passé à un numéro1 (équivalent à Number(x)) puis teste si la valeur est NaN. Si le paramètre ne peut pas être convertie en nombre, Number(x) sera de retour NaN2. Par conséquent, si la conversion de paramètre x pour un certain nombre de résultats en NaN, il renvoie vrai; sinon, elle renvoie false.

Ainsi, dans le cas spécifique x = null, null est ramené au nombre 0, (essayez d'évaluation Number(null) et de voir qu'elle retourne 0,) et isNaN(0) renvoie la valeur false. Une chaîne qui est uniquement des chiffres peut être converti en nombre et isNaN également retourne false. Une chaîne de caractères (par exemple, 'abcd') qui ne peuvent être converties en un nombre causer isNaN('abcd') retourner la valeur true, précisément parce qu' Number('abcd') retours NaN.

En plus de ces apparente cas limites sont la norme numérique raisons pour le retour NaN comme 0/0.

Comme pour l'apparence contradictoires tests pour l'égalité de la question, le comportement de l' NaN est spécifié de telle sorte que toute comparaison x == NaN est faux, indépendamment de l'autre opérande, y compris NaN lui-même1.

43voto

guy mograbi Points 2418

Je viens de tomber sur ce problème moi-même.

Pour moi, la meilleure façon d'utiliser isNaN est comme si

isNaN(parseInt(myInt))

la prise de phyzome l'exemple ci-dessus,

var x = [undefined, NaN,     'blah', 0/0,  null, 0,     '0',   1,     1/0, -1/0,  Number(5)]
x.map( function(n){ return isNaN(parseInt(n))})
        [true,      true,    true,   true, true, false, false, false, true, true, false]

( J'ai aligné le résultat en fonction de l'entrée, de l'espoir, il le rend plus facile à lire. )

Cela me semble mieux.

11voto

phyzome Points 1032

C'est vraiment inquiétant. Voici un tableau de valeurs que j'ai testé:

var x = [undefined, NaN, 'blah', 0/0, null, 0, '0', 1, 1/0, -1/0, Number(5)]

Il évalue (dans la console de Firebug):

,NaN,blah,NaN,,0,0,1,Infinity,-Infinity,5

Quand je l'appelle x.map(isNaN) (pour appeler isNaN sur chaque valeur), j'obtiens:

true,true,true,true,false,false,false,false,false,false,false

En conclusion, isNaN semble assez inutile!

D'ailleurs, voici le type de ces valeurs:

x.map(function(n){return typeof n})
-> undefined,number,string,number,object,number,string,number,number,number,number

11voto

phyzome Points 1032

(Mon autre commentaire prend une approche pratique. Voici le côté théorique.)

J'ai regardé l' ECMA 262 standard, ce qui est le Javascript met en œuvre. Leur cahier des charges pour isNan:

S'applique ToNumber de son argument, puis renvoie la valeur true si le résultat est NaN, et sinon, renvoie false.

La Section 9.3 spécifie le comportement de l' ToNumber (ce qui n'est pas une fonction appelable, mais plutôt une composante de la conversion de type de système). Pour résumer la table, certains types d'entrée peut produire un NaN. Ce sont de type undefined, tapez number (mais seulement la valeur NaN), tout objet dont les primitives de représentation est - NaN, et tout string qui ne peuvent pas être analysés. Cela laisse undefined, NaN, new Number(NaN), et la plupart des chaînes.

Une telle entrée qui produit NaN de sortie lorsqu'il est passé à l' ToNumber va produire un true lorsque la fed isNaN. Depuis null peut être converti en un nombre, il ne produit pas d' true.

Et c'est pourquoi.

6voto

moonshadow Points 28302

isNaN regarde pour les valeurs numériques qui ne sont pas des nombres - des choses comme l'infini, undeflow etc.; vous pourriez penser à eux comme à des codes d'erreur pour les calculs. null n'est pas un de ces.

Plus d'informations ici.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X