J'ai dû écrire une routine qui incrémente la valeur d'une variable de 1 si son type est number
et affecte 0 à la variable sinon, où la variable est initialement null
ou undefined
.
La première implémentation était v >= 0 ? v += 1 : v = 0
parce que je pensais que tout ce qui n'est pas un nombre rendrait une expression arithmétique fausse, mais c'était faux car il null >= 0
est évalué à vrai. Ensuite, j'ai appris qu'il null
se comporte comme 0 et les expressions suivantes sont toutes évaluées à vrai.
null >= 0 && null <= 0
!(null < 0 || null > 0)
null + 1 === 1
1 / null === Infinity
Math.pow(42, null) === 1
Bien sûr, null
n'est pas 0. null == 0
est évalué à faux. Cela rend l'expression apparemment tautologique (v >= 0 && v <= 0) === (v == 0)
fausse.
Pourquoi est null
comme 0, bien que ce ne soit pas réellement 0?
javascript
null
comparison
equality
C. Lee
la source
la source
null
soitundefined
:c = -~c // Results in 1 for null/undefined; increments if already a number
undefined
est une valeur de variable, pour les variables qui n'ont pas été initialisées.null
, d'autre part, est une valeur d'objet vide et ne doit pas être mélangée avec des nombres.null
ne doit pas être combiné avec des nombres, donc null ne devrait pas avoir à se comporter comme des nombres.Réponses:
Votre vraie question semble être:
Pourquoi:
Mais:
Ce qui se passe vraiment, c'est que l' Opérateur Supérieur ou égal (
>=
), effectue la coercition de type (ToPrimitive
), avec un type d' indication deNumber
, en fait tous les opérateurs relationnels ont ce comportement.null
est traité d'une manière spéciale par l' opérateur égal (==
). Dans un bref, il ne contraint qu'àundefined
:Valeur telle que
false
,''
,'0'
et[]
sont soumis à la contrainte de type numérique, tous les contraignent à zéro.Vous pouvez voir les détails internes de ce processus dans l' algorithme de comparaison d'égalité abstraite et l'algorithme de comparaison relationnelle abstraite .
En résumé:
Comparaison relationnelle: si les deux valeurs ne sont pas de type String,
ToNumber
est appelée sur les deux. C'est la même chose que d'ajouter un+
devant, qui pour null contraint à0
.Comparaison d'égalité: n'appelle que
ToNumber
les chaînes, les nombres et les booléens.la source
null is treated in a special way by the Equals Operator (==). In a brief, it only coerces to undefined:
- et quoi? Pouvez-vous expliquer pourquoinull >= 0
? :)+
devant, qui pour null contraint à0
. L'égalité appelle uniquement ToNumber sur les chaînes, les nombres et les booléens.Je voudrais étendre la question pour améliorer encore la visibilité du problème:
Cela n'a tout simplement aucun sens. Comme les langues humaines, ces choses doivent être apprises par cœur.
la source
JavaScript propose des comparaisons strictes et de conversion de type
null >= 0;
est vrai mais(null==0)||(null>0)
est fauxnull <= 0;
est vrai mais(null==0)||(null<0)
est faux"" >= 0
est aussi vraiPour les comparaisons abstraites relationnelles (<=,> =), les opérandes sont d'abord convertis en primitives, puis du même type, avant comparaison.
typeof null returns "object"
Lorsque le type est un objet, javascript tente de stringifier l'objet (c'est-à-dire null), les étapes suivantes sont suivies ( ECMAScript 2015 ):
PreferredType
n'est pas passé, laissezhint
être "par défaut".PreferredType
esthint
String,hint
soit "string".PreferredType
esthint
Nombre, nous allonshint
être « nombre ».exoticToPrim
êtreGetMethod(input, @@toPrimitive)
.ReturnIfAbrupt(exoticToPrim)
.exoticToPrim
n'est pas indéfini, alorsa) Soit le résultat
Call(exoticToPrim, input, «hint»)
.b)
ReturnIfAbrupt(result)
.c) Si
Type(result)
n'est pas Object, renvoie le résultat.d) Lancez une exception TypeError.
hint
est "par défaut",hint
soit "nombre".OrdinaryToPrimitive(input,hint)
.Les valeurs autorisées pour l'indice sont "par défaut", "nombre" et "chaîne". Les objets Date sont uniques parmi les objets ECMAScript intégrés en ce sens qu'ils traitent "default" comme étant équivalent à "string". Tous les autres objets ECMAScript intégrés considèrent «default» comme étant équivalent à «number» . ( ECMAScript 20.3.4.45 )
Donc je pense qu'il se
null
convertit à 0.la source
J'ai eu le même problème !!. Actuellement, ma seule solution est de me séparer.
la source
if (a!=null && a>=0)
. Ceci clarifie la raison de ne pas simplement faire>=
par lui-même: "a pourrait être nul (ou non défini, qui est aussi '== null')".Mathématiquement, c'est étrange. Le dernier résultat indique que "null est supérieur ou égal à zéro", donc dans l'une des comparaisons ci-dessus, il doit être vrai, mais ils sont tous les deux faux.
La raison en est qu'un contrôle d'égalité
==
et des comparaisons> < >= <=
fonctionnent différemment. Les comparaisons convertissent null en nombre, le traitant comme0
. C'est pourquoi (3)null >= 0
esttrue
et (1)null > 0
estfalse
.D'autre part, le contrôle de l' égalité
==
pourundefined
etnull
est définie de telle sorte que, sans aucune conversion, ils sont égaux entre eux et ne sont pas égaux quoi que ce soit d' autre. C'est pourquoi (2)null == 0
estfalse
.la source