Logo JavaScript

Énigme JavaScript avec +

Flattr this!

Et si on jouait avec JavaScript ? La question est :

Pourquoi :

 

++[[]][+[]]+[+[]] = 10

Vous l'avez pas vu venir celle-là hein 😉

Si si, en JS, ce code est valide et vaut bien 10, testez.

Explication

Découpons l'opération :

++[[]][+[]] // -> A
+
[+[]] // -> B

On a deux parties bien distinctes A et B. D'ailleurs, on retrouve B dans A, ce qui va nous simplifier la vie. Résolvons B d'abord pour faire simple :

[+[]]

Comme vous le savez, quand il précède quelque chose, le signe + transforme en entier, ou essaie, tout ce qu'il touche. En l'occurrence, ici, il transforme un tableau vide. Ce qui vaut 0.

Nous obtenons donc un tableau qui contient un seul élément ayant pour valeur 0. Soit :

B = [0]

Précisions concernant les transformations avec l'opérateur +

Cette transformation ne fonctionne que sur les éléments de type alphanumériques. C'est à dire que :

+[] == 0
+"" == 0
+{} // erreur : NaN

Passons à A

On peut donc simplifier désormais :

++[[]][+[]]

en

++[[]][0]

Vu que [0] retourne le premier élément du tableau auquel il est attaché, on peut encore simplifier :

++[]

Alors là la magie est "simple". Vous connaissez tous le principe simple d'écrire :

var maVar = 2;
++maVar; // maVar = 3

plutôt que

var maVar = 2;
maVar = maVar + 1; // maVar = 3
maVar +=  1; // maVar = 4

Bon et bien c'est ce qu'on fait dans le cas de A. Ici, on incrémente de 1, un tableau vide qui donc "transformer" en entier vaut 0.

++[]
++0 // attention invalide mais pour vous montrer les étapes
1

Résultat

Nous arrivons donc avec une formule simplifiée en réunissant à nouveau A et B :

1 + [0]

Et là on retrouve une autre des fonctions du + en JavaScript : la concaténation. Vu qu'un des deux opérateurs en présence n'est pas un nombre, il concatène et ne fait pas l'addition. Nous voyons donc notre tableau se transformer en chaîne :

[0] == "0"

Ce qui donne :

1 + "0"

D'où le 10.

Résumé

Vous venez en une seule formule revu les différentes facettes de l'opérateur + en JavaScript :

  • la transformation en entier +[] == 0 ;
  • l'incrémentation à la volée d'une valeur convertie ++[] qui donne 1 ;
  • et la concaténation avec 1 + [0] qui donne 10.

Et vous avez même bénéficié d'un rappel sur le fait qu'en JS aussi, une chaîne n'est finalement qu'un tableau de caractères.

Classe le JS quand même, non ?! 😉

Flattr this!

A propos de Mathieu

Ingénieur développeur web dans la vente par correspondance B2B, adepte de nouvelles technologies et d'innovation. Vous pouvez aussi me retrouver sur Twitter @mathrobin
Cette entrée a été publiée dans JavaScript, avec comme mot(s)-clef(s) , , . Vous pouvez la mettre en favoris avec ce permalien.
  • Nikouf

    J’arrive à comprendre que ++[+[]][+[]] == 1
    Mais pas que ++[[]][+[]] == 1. En fait c’est le raccourci ++[] = 1 qui me dérange…
    Et j’ai une seconde énigme :
    Pourquoi cette écriture est valide et vaut « 0 » : [[]][+[]]+++[]
    Merci ^^

    • http://www.mathieurobin.com/ Mathieu

      Salut!
      Alors pour le raccourci, il est un peu magique en effet.
      ++[] peut être découpé en :
      var a = +[];
      ++a;
      C’est à dire qu’à la première ligne (et comme vu dans l’article) a vaut 0. Puis si tu cherches bien, tu verras que faire ++a incrémente a de 1. D’où le raccourci ++[] qui vaut 1
      Je vais m’amuser avec ta seconde énigme et sûrement faire un billet explicatif. Ceci dit, ce genre d’écritures sont à prohiber. Elles sont relativement incompréhensibles, illisibles et donc avec tous les soucis qui y sont liés.

  • http://cahnory.tumblr.com/ cahnory

    Ça m’a fait pensé à ça : https://www.destroyallsoftware.com/talks/wat :)

Articles liés