Javascript Concatenation

J'ai rencontré l'extrait de codes suivant dans un quiz javascript en ligne. Je ne pouvais pas comprendre comment cette concaténation fonctionne dans JS. Quelqu'un peut-il expliquer comment cela fonctionne?

[] + [] = "" // output : "" [] + [] + "foo" // output : "foo" 

Javascript essaie d'appliquer l'opérateur + de différentes manières, il a été enseigné.

Donc, à moins qu'il ne soit expliqué explicitement, il appelle la méthode toString de la matrice qui est la meilleure estimation quand on lui dit d'ajouter deux tableaux.

 [] + [] = "" +[] + [] = "0" // If you give a hint to cast one of the array to a Number +[] + +[] = 0 // If you give a hint to cast both the arrays to Number 

Alors que [] + [] + "foo" est tout simplement

 ([] + []) + "foo" = "" + "foo" = "foo" 

Lorsque vous dites [] + [] , JavaScript tente de convertir les opérandes en nombres.

Selon la spécification ECMA 5.1 de l'opérateur supplémentaire ,

 4. Let lprim be ToPrimitive(lval). 5. Let rprim be ToPrimitive(rval). 

Donc, d'abord, ils sont tentés de convertir en valeurs primitives avec ToPrimitive . Comme Arrays sont des objets, JavaScript essaie de récupérer les valeurs par défaut et de les utiliser comme valeurs primitives.

Renvoie une valeur par défaut pour l'objet. La valeur par défaut d'un objet est récupérée en appelant la méthode interne [[DefaultValue]] de l'objet, en passant l'indice optionnel PreferredType. Le comportement de la méthode interne [[DefaultValue]] est défini par cette spécification pour tous les objets ECMAScript natifs dans 8.12.8.

Lorsque DefaultValue est appelé sans aucun indice, il considérera cela comme Numéro, par défaut.

Lorsque la méthode interne [[DefaultValue]] de O est appelée sans indice, elle se comporte comme si l'indice était Numéro, sauf si O est un objet Date (voir 15.9.6), auquel cas il se comporte comme si l'indice était Chaîne.

Et la valeur par défaut est récupérée comme celle-ci

 1. Let valueOf be the result of calling the [[Get]] internal method of object O with argument "valueOf". 2. If IsCallable(valueOf) is true then, a. Let val be the result of calling the [[Call]] internal method of valueOf, with O as the this value and an empty argument list. b. If val is a primitive value, return val. 3. Let toString be the result of calling the [[Get]] internal method of object O with argument "toString". 4. If IsCallable(toString) is true then, a. Let str be the result of calling the [[Call]] internal method of toString, with O as the this value and an empty argument list. b. If str is a primitive value, return str. 5. Throw a TypeError exception. 

Donc, il essaie d'obtenir la valeur de l'objet et tente d'exécuter cela, ce qui renvoie [] et ce n'est pas une valeur primitive. La valeur primitive est définie comme celle-ci

Membre de l'un des types Indéfini, Null, Boolean, Number ou String tel que défini à l'article 8.

Comme aucun d'eux ne peut être converti en valeurs primitives, ils sont convertis en chaînes avec toString . Puisqu'ils sont des tableaux vides, les valeurs de chaîne sont également des chaînes vides.

C'est pourquoi

 console.log([] + [] === ""); # true