Pourquoi «,,,» == Array (4) en Javascript?


119

Démarrez votre interpréteur / console et essayez la comparaison

> ",,," == Array(4)
True

Pourquoi? Au début, je pensais que peut-être puisque vous pouviez penser à ",,," comme un tableau de quatre caractères avec une tranche de fin '\ 0', c'est peut-être pourquoi, mais

> "..." == Array(4)

Renvoie "False". Alors pourquoi? Je sais que c'est un peu idiosyncratique de frappe de canard en Javascript, mais je suis juste curieux de savoir ce qui souligne ce comportement. J'ai glané cela de l'excellente présentation de Zed Shaw ici d'ailleurs .


14
Peu de langages en dehors du C utilisent la terminaison zéro d'une manière visible pour le programmeur.
Joey

7
Si je puis demander, qu'est-ce qui a conduit à cette découverte?
SomeKittens

1
@SomeKittens Zed Shaw mentionne cela explicitement dans la vidéo à laquelle j'ai lié dans ma question (comme une critique de Javascript). À votre santé!
ZenLikeThat

5
@SomeKittens Ceci est également mentionné dans la (assez bien connue) "wat" talk, montrant quelques bizarreries dans Ruby et JavaScript destroyallsoftware.com/talks/wat
Cronco

5
C'est l'une des nombreuses bonnes raisons de toujours utiliser à la ===place de ==.
wprl

Réponses:


178

Parce que l'opérande de droite est converti en chaîne et que la représentation sous forme de chaîne de Array(4)est ,,,:

> Array(4).toString()
  ",,,"

Si vous utilisez la fonction de constructeur de tableau et passez un nombre, il définit la longueur du tableau sur ce nombre. Vous pouvez donc dire que vous avez quatre index vides (identiques à [,,,]) et que la représentation sous forme de chaîne par défaut des tableaux est une liste séparée par des virgules de ses éléments:

> ['a','b','c'].toString()
  "a,b,c"

Le fonctionnement de la comparaison est décrit dans la section 11.9.3 de la spécification . Là vous verrez ( x == y):

8. Si Type ( x ) est Chaîne ou Nombre et Type ( y ) est Objet,
renvoyez le résultat de la comparaison x == ToPrimitive ( y ).

(les tableaux sont des objets en JavaScript)

et si vous suivez la ToPrimitiveméthode, vous finirez par trouver qu'elle appelle toString.


2
Ok, maintenant tout cela a un sens pour moi. Merci.
ZenLikeThat

6
Ce qui, à son tour, est dû au fait que les tableaux se stringifient comme s'ils utilisaient Array.join(",").
duskwuff -inactive-

Il faut être patient pour programmer en javascript
matcheek


31

Essayez d'utiliser ===. Lors de l'utilisation ==en Javascript, il tentera de convertir les variables, conduisant ainsi à des problèmes comme celui-ci. La console effectue un cast Array(4)vers la représentation sous forme de chaîne (c'est-à-dire Array(4).toString), qui est ",,,". La raison pour laquelle les virgules sont là est que la .toString()fonction les ajoute à des éléments séparés dans un tableau.

Voir l'extrait ci-dessous:

document.write( Array(4).toString() );


18

C'est parce que Array(4)initialise un tableau de 4 valeurs vides, et ==convertit implicitement, donc:

 ",,," == Array(4)

 ",,," == Array(4).toString()

 ",,," == ["", "", "", ""] // note 3 commas for 4 values

 ",,," == ["", "", "", ""].toString()

Sont tous similaires.

==effectue des conversions de type implicites avant de comparer les valeurs, ce qui peut entraîner des résultats imprévisibles. Utilisez ===pour vérifier le type et la valeur.


5

La comparaison d'un tableau à une chaîne contraint le tableau à une chaîne avant d'effectuer la comparaison. La contrainte d'un tableau à 4 éléments vide en une chaîne donne cette chaîne exacte.


4

J'ai d'abord pensé que c'était quelque chose avec le "prototype" ... mais après une petite enquête, je suis arrivé à une triste conclusion ...

Apparemment c'est une chose js interne et plus obscure avec pas beaucoup de logique ...

Essayez juste

Array(4)==Array(4)

et pas de coercition sur les types aussi ...

Array(4)===Array(4)

et vous obtiendrez FAUX

vous le savez null==null, null===nullet même undefined==undefinedet undefined===undefinedretourne TRUE ... alors ... c'est un peu obscur ...

Array(4)==[,,,] devrait être vrai aussi


ZEE, Array (4) == [,,,] ne sera pas vrai. Si nous comparons l'objet avec le primitif, alors l'objet sera converti en primitif. C'est la raison pour laquelle il appelle toString ().
devsathish

array (x) devrait être l'adresse du constructeur ... de toute façon, dans un système (ne vous inquiétez pas du type de système), <identity_X> === <identity_X> devrait toujours être vrai!
ZEE
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.