Pourquoi “” == true en JavaScript?

Je sais que JavaScript a beaucoup de résultats insensés avec des comparaisons entre les types, même si je ne comprends pas bien pourquoi. Je suis venu à travers celui-ci aujourd’hui.

Pourquoi

"" == [null] 

évaluer true en JavaScript?

Un peu plus d’amusement d’égalité Javascript, grâce à @Qantas:

  • Pourquoi 2 == [2] en JavaScript?
  • Pourquoi 0 == “” vrai en JavaScript
  • Pourquoi si ([]) est validé alors que [] == false en javascript?
  • Pourquoi est-ce que {} [true] est vrai en JavaScript?

L’ algorithme de comparaison d’égalité abstraite comporte de nombreuses parties, mais l’important est le suivant:

Si Type ( x ) est soit Ssortingng, soit Number et Type ( y ) est Object, renvoyer le résultat de la comparaison x == ToPrimitive ( y ).

(Il y a aussi une image miroir). Donc, parce que "" est une chaîne et [null] est un object, nous devons d’abord convertir [null] en une chaîne en appelant ToPrimitive([null]) . C’est une opération interne décrite comme suit, quand il est demandé de convertir une instance Object en une valeur primitive:

Renvoie une valeur par défaut pour l’object. La valeur par défaut d’un object est extraite en appelant la méthode interne [[DefaultValue]] de l’object, en transmettant l’indicateur optionnel PreferredType . Le comportement de la méthode interne [[DefaultValue]] est défini par cette spécification pour tous les objects ECMAScript natifs du 8.12.8.

A présent, l’opération interne [[DefaultValue]] appelle .toSsortingng() sur l’object et renvoie cette valeur. Essayez [null].toSsortingng() dans la console de votre navigateur:

 > [null].toSsortingng() "" 

Et voila.

Edit: Et pourquoi [null].toSsortingng() une chaîne vide? Parce que l’opération .toSsortingng() sur les instances Array appelle toujours simplement .join() , ce qui donne toujours une chaîne vide pour null valeurs null et undefined . Ainsi, un tableau d’un null se termine par une simple chaîne vide.

C’est selon les règles de conversion de type arcane de Javascript. Règle n ° 8:

Si Type (x) est soit Ssortingng, soit Number et Type (y) est Object, renvoyer le résultat de la comparaison x == ToPrimitive (y).

Donc, la comparaison est entre x = "" et y = [null] converti en une chaîne en utilisant ToPrimitive . La conversion d’un tableau avec un élément nul entraîne une chaîne vide (car Array.toSsortingng() renvoie une liste de valeurs séparées par des virgules), ce qui Array.toSsortingng() qu’elles sont égales.

Pourquoi "" == [null] vrai?

Comme vous comparez un tableau avec une chaîne, en utilisant l’ opérateur d’égalité non ssortingct == – il essaiera donc de convertir les valeurs vers le même type avant de les comparer.

Ce qui se passe en détail est:

  1. vous comparez une chaîne à un object, de sorte que l’object est converti en chaîne:
  2. Lorsqu’un tableau est .toSsortingng() en une valeur primitive, sa méthode .toSsortingng() est invoquée (comme expliqué en détail par les autres réponses), ce qui équivaut à appeler .join() :
  3. qui, dans le cas d’un tableau à un élément qui ne contient qu’une valeur undefined ou null , renvoie la chaîne vide
  4. qui est finalement équivalent à la chaîne vide

Cette troisième étape est inattendue ( [null]+"" != null+"" ), si elle a effectivement été convertie en chaîne, le résultat aurait été "null" et votre égalité serait fausse.

Regardons les spécifications et suivons chaque étape

Passer par l’ algorithme de comparaison d’égalité abstraite (§11.9.3) :

  1. typeof ""; // ssortingng typeof ""; // ssortingng et typeof [null]; // object typeof [null]; // object si non applicable
  2. aucun n’est null ou undefined donc non applicable
  3. identique à 2
  4. aucun n’est un nombre, sans object
  5. même que 4
  6. aucun n’est un bool, sans object
  7. encore non applicable
  8. enfin, quelque chose applicable, maintenant nous devons savoir ToPrimitive([null])

§9.1 ToPrimitive for Objects dit que nous devons travailler sur [[DefaultValue]] (§8.12.8) , dont les points 1 et 2 indiquent si vous pouvez faire .toSsortingng et qu’il donne une chaîne, renvoyez-le, donc

 [null].toSsortingng(); // "" 

Nous effectuons donc maintenant la comparaison "" == "" ce qui est true au point 1 de l’ algorithme de comparaison d’égalité abstraite . D.

Si Type(x) est Ssortingng , retournez true si x et y sont exactement la même séquence de caractères (même longueur et mêmes caractères aux positions correspondantes). Sinon, retournez false .

JavaScript est faiblement typé; vous pouvez utiliser les éléments suivants pour obtenir un résultat faux:

 "" === [null] 

La valeur null est un littéral JavaScript représentant la valeur null ou une valeur “vide”, c’est-à-dire qu’aucune valeur d’object n’est présente. C’est l’une des valeurs primitives de JavaScript.

La valeur null est un littéral (pas une propriété de l’object global comme undefined peut être). Dans les API, null est souvent récupéré à l’endroit où un object peut être attendu, mais aucun object n’est pertinent. Lors de la vérification de null ou indéfini, prenez garde aux différences entre les opérateurs d’égalité (==) et d’identité (===) (la conversion de type est effectuée avec l’ancien).

 typeof null // object (bug in ECMAScript, should be null) typeof undefined // undefined null === undefined // false null == undefined // true