66 votes

Pourquoi !!1=="1" est-il égal à vrai et !!2=="2" à faux ?

Comme le titre l'indique, pourquoi :

> !!1=="1"

égal

True

et

> !!2=="2"

égal :

False

De même, pourquoi > "1"==true égal true y > "2"==true égal false

Je suis déconcerté. Est-ce que ce sont juste des bugs dans JS ou qu'est-ce qui se passe ici ?

208voto

thefourtheye Points 56958

Conformément à la Préséance des opérateurs règles, logique ! a une priorité plus élevée que == . Donc, dans les deux cas, !! est évalué en premier.

Note : La véracité de différents objets a été expliquée dans cette réponse de la mienne.

Premier cas

!!1 == "1"

!1 sera évalué à false ya que 1 est considéré comme Truthy. En négationnant encore, on obtient true . L'expression devient donc

true == "1"

Maintenant, les règles de coercition entrent en jeu puisque vous avez utilisé == qui s'évalue selon la méthode L'algorithme de comparaison d'égalité abstraite défini dans la spécification ECMAScript 5.1,

6. Si Type(x) es Boolean retourne le résultat de la comparaison ToNumber(x) == y .

Donc, true sera converti en un nombre, qui est 1 selon ToNumber algorithme pour les valeurs booléennes . Maintenant l'expression devient

1 == "1"

Maintenant,

4. Si Type(x) es Number y Type(y) es String , retourne le résultat de la comparaison x == ToNumber(y) .

Donc, "1" sera converti en un nombre et cela donnera 1, conformément à la règle du ToNumber algorithme . C'est pourquoi il montre true dans le premier cas.

Deuxième cas

Les mêmes règles sont appliquées ici.

!!2 == "2"

devient

true == "2"

entonces

1 == "2"

qui devient

1 == 2

qui n'est pas true c'est pourquoi le deuxième cas s'imprime false .

13voto

user2864740 Points 18869

Tldr ; ceci est dû à la [ToNumber] les conversions dans le == algorithme de l'opérateur.

La première étape consiste à simplifier l'expression. Puisque !!x=="x" est analysé comme (!!x)=="x" y !!a_truthy_expression -> true l'expression pertinente réelle de l'égalité est

!!1=="2" -> true=="1" -> Boolean==String
!!2=="2" -> true=="2" -> Boolean==String

Donc, en regardant les règles pour 11.9.3 L'algorithme de comparaison d'égalité abstraite et en suivant les rendements de l'application

Règle 6 - Si Type(x) est booléen, retourner le résultat de la comparaison ToNumber(x) == y.

ce qui entraîne Number==String ou 1=="1" et 1=="2", respectivement. 1 . Alors la règle

Règle 7 - Si Type(x) est un nombre et Type(y) est une chaîne, retourne le résultat de la comparaison x == ToNumber(y).

est appliquée, ce qui donne lieu à Number==Number ou 1==1 et 1==2, respectivement 1 ; ce dernier point est clairement faux.

Règle 1 - Si Type(x) est le même que Type(y), alors [par c.iii.] Si x est la même valeur numérique que y, retourner true [else return false].

(Le même algorithme explique le String==Boolean cas lorsque les règles de complémentarité sont appliquées).


1 Pour voir l'application de la règle [ToNumber], considérez :

+false -> 0
+true  -> 1
+"1"   -> 1
+"2"   -> 2

5voto

C'est un problème d'opérateur de précédence.

El ! est un opérateur unaire. Cela signifie que le côté gauche doit être une expression ou une section booléenne évaluable. Voir Javascript MDN .

!!1==1 is not necessary !!(1==1)
!!2==2 is not necessary !!(2==2)

Je pense que ces expressions devraient être cohérentes si l'opérateur égal a plus de priorité que l'opérateur ! Mais si nous considérons l'inverse, en évaluant les premières négations que nous avons :

!!1 == 1
!1 -> false
!!1 -> true
!!1 == 1 

Et avec les deux

!!2==2
!2 -> false
!!2 -> true
(!!2) == 2 -> false

C'est parce que l'opérateur ! a la priorité sur l'opérateur ==.

Ver Préférence de l'opérateur Mozilla

1voto

Meredith Points 612

!!1 est égal à vrai, et "1" est égal à vrai ("0" est faux, tout comme les autres chaînes). Donc !!1 == "1" évalue à true == true qui, bien sûr, renvoie vrai.

!!2 est également égal à vrai. Comme je l'ai mentionné précédemment, "2" n'est pas "1", donc c'est faux. Par conséquent, nous avons true == false qui renvoie bien sûr un résultat faux.

Si vous voulez savoir si 2 (un nombre) est égal à "2" (une chaîne de caractères représentant un nombre), il vous suffit de faire ce qui suit 2 == "2" ce qui donne 2 == 2 ce qui est vrai. La différence est que nous ne comparons pas un booléen avec un booléen. Nous comparons un nombre à un nombre.

En gros, mettre !! devant un nombre se convertit en booléen, ce qui oblige JavaScript à convertir votre chaîne en booléen au lieu d'un nombre.

-1voto

Miraage Points 1179

Parce que "1" peut être considéré comme "vrai" lorsque vous faites un contrôle d'égalité, pas d'identité, mais "2" - ne peut pas.

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