J'ai récemment découvert cela 2 == [2]
en JavaScript. En fait, cette bizarrerie a quelques conséquences intéressantes:
var a = [0, 1, 2, 3];
a[[2]] === a[2]; // this is true
De même, les travaux suivants:
var a = { "abc" : 1 };
a[["abc"]] === a["abc"]; // this is also true
Encore plus étrange encore, cela fonctionne aussi:
[[[[[[[2]]]]]]] == 2; // this is true too! WTF?
Ces comportements semblent cohérents sur tous les navigateurs.
Une idée de la raison pour laquelle il s'agit d'une fonctionnalité linguistique?
Voici les conséquences plus insensées de cette "fonctionnalité":
[0] == false // true
if ([0]) { /* executes */ } // [0] is both true and false!
var a = [0];
a == a // true
a == !a // also true, WTF?
Ces exemples ont été trouvés par jimbojw http://jimbojw.com fame ainsi que walkingeyerobot .
+"2"
est aussi le numéro 2.Sur le côté droit de l'équation, nous avons le a [2], qui renvoie un type de nombre avec la valeur 2. Sur la gauche, nous créons d'abord un nouveau tableau avec un seul objet de 2. Ensuite, nous appelons a [( tableau est ici)]. Je ne sais pas si cela correspond à une chaîne ou à un nombre. 2 ou "2". Prenons d'abord la casse de la chaîne. Je crois qu'un ["2"] créerait une nouvelle variable et renverrait null. null! == 2. Supposons donc qu'il se convertit implicitement en un nombre. a [2] renverrait 2. 2 et 2 correspondent au type (donc === fonctionne) et à la valeur. Je pense qu'il convertit implicitement le tableau en un nombre car une [valeur] attend une chaîne ou un nombre. Il semble que le nombre ait une priorité plus élevée.
En passant, je me demande qui détermine cette préséance. Est-ce parce que [2] a un nombre comme premier élément, donc il se convertit en un nombre? Ou est-ce que lors du passage d'un tableau dans un [tableau], il essaie d'abord de transformer le tableau en nombre, puis en chaîne. Qui sait?
Dans cet exemple, vous créez un objet appelé a avec un membre appelé abc. Le côté droit de l'équation est assez simple; c'est équivalent à a.abc. Cela renvoie 1. Le côté gauche crée d'abord un tableau littéral de ["abc"]. Vous recherchez ensuite une variable sur un objet en passant le tableau nouvellement créé. Comme cela attend une chaîne, il convertit le tableau en une chaîne. Cela évalue maintenant à un ["abc"], qui est égal à 1. 1 et 1 sont du même type (c'est pourquoi === fonctionne) et de valeur égale.
Ceci est juste une conversion implicite. === ne fonctionnerait pas dans cette situation car il y a une incompatibilité de type.
la source
==
s'appliqueToPrimitive()
au tableau, qui à son tour invoque satoString()
méthode, donc ce que vous comparez réellement est le nombre2
à la chaîne"2"
; la comparaison entre une chaîne et un nombre se fait en convertissant la chaînePour le
==
cas, c'est pourquoi Doug Crockford recommande de toujours utiliser===
. Il ne fait aucune conversion de type implicite.Pour les exemples avec
===
, la conversion de type implicite est effectuée avant l'appel de l'opérateur d'égalité.la source
C'est intéressant, ce n'est pas que [0] soit à la fois vrai et faux, en fait
C'est la manière amusante de javascript de traiter l'opérateur if ().
la source
==
fonctionner; si vous utilisez un cast explicite réel (c'est-àBoolean([0])
- dire ou!![0]
), vous constaterez que cela[0]
sera évaluétrue
dans des contextes booléens comme il se doit: dans JS, tout objet est considérétrue
Un tableau d'un élément peut être traité comme l'élément lui-même.
Cela est dû au typage du canard. Depuis "2" == 2 == [2] et peut-être plus.
la source
==
opérateur avant la comparaison.Pour ajouter un peu de détail aux autres réponses ... lorsque vous comparez un
Array
à unNumber
, Javascript convertira leArray
avecparseFloat(array)
. Vous pouvez l'essayer vous-même dans la console (par exemple Firebug ou Web Inspector) pour voir en quoi les différentesArray
valeurs sont converties.Pour
Array
s,parseFloat
exécute l'opération sur leArray
premier membre de s, et rejette le reste.Edit: Selon les détails de Christoph, il se peut qu'il utilise le formulaire le plus long en interne, mais les résultats sont toujours identiques à
parseFloat
, vous pouvez donc toujours utiliserparseFloat(array)
comme raccourci pour savoir avec certitude comment il sera converti.la source
Vous comparez 2 objets dans chaque cas. N'utilisez pas ==, si vous pensez à la comparaison, vous avez === en tête et non ==. == peut souvent donner des effets insensés. Cherchez les bonnes parties dans la langue :)
la source
Explication de la section EDIT de la question:
1er exemple
Premier typage [0] à une valeur primitive selon la réponse de Christoph ci-dessus, nous avons "0" (
[0].valueOf().toString()
)Maintenant, tapez Boolean (false) en Number, puis String ("0") en Number
Comme pour l'
if
instruction, s'il n'y a pas de comparaison explicite dans la condition if elle-même, la condition évalue les valeurs de vérité .Il n'y a que 6 valeurs fausses: false, null, undefined, 0, NaN et une chaîne vide "". Et tout ce qui n'est pas une valeur fausse est une valeur de vérité.
Puisque [0] n'est pas une valeur falsifiée, c'est une valeur de vérité, l'
if
instruction prend la valeur true & exécute l'instruction.2ème exemple
Encore une fois, tapez les valeurs de conversion primitive
la source