Je voulais ajouter les éléments d'un tableau dans un autre, j'ai donc essayé ceci:
[1,2] + [3,4]
Il a répondu par:
"1,23,4"
Que se passe-t-il?
[5,6,7][1,2]
est 7
parce qu'il utilise le dernier élément dans le second tableau. Oo
Je voulais ajouter les éléments d'un tableau dans un autre, j'ai donc essayé ceci:
[1,2] + [3,4]
Il a répondu par:
"1,23,4"
Que se passe-t-il?
[5,6,7][1,2]
est 7
parce qu'il utilise le dernier élément dans le second tableau. Oo
Réponses:
L' +
opérateur n'est pas défini pour les tableaux .
Ce qui se passe, c'est que Javascript convertit les tableaux en chaînes et les concatène.
Étant donné que cette question et, par conséquent, ma réponse suscitent beaucoup d'attention, j'ai pensé qu'il serait utile et pertinent d'avoir également une vue d' ensemble du +
comportement de l' opérateur en général.
Alors, c'est parti.
À l'exception d'E4X et des éléments spécifiques à l'implémentation, Javascript (à partir d'ES5) dispose de 6 types de données intégrés :
Notez que bien que renvoyant de façon typeof
quelque peu confuse object
pour Null et function
pour les objets appelables, Null n'est en fait pas un objet et à proprement parler, dans les implémentations Javascript conformes aux spécifications, toutes les fonctions sont considérées comme des objets.
C'est vrai - Javascript n'a pas de tableaux primitifs en tant que tels; seules les instances d'un objet appelé Array
avec du sucre syntaxique pour soulager la douleur.
Pour ajouter à la confusion, les entités wrapper telles que new Number(5)
, new Boolean(true)
et new String("abc")
sont toutes de object
type, pas des nombres, des booléens ou des chaînes comme on pourrait s'y attendre. Néanmoins pour les opérateurs arithmétiques Number
et Boolean
se comportent comme des nombres.
Facile, hein? Avec tout cela à l'écart, nous pouvons passer à l'aperçu lui-même.
Différents types de résultats par types d' +
opérande
|| undefined | null | boolean | number | string | object |
=========================================================================
undefined || number | number | number | number | string | string |
null || number | number | number | number | string | string |
boolean || number | number | number | number | string | string |
number || number | number | number | number | string | string |
string || string | string | string | string | string | string |
object || string | string | string | string | string | string |
* s'applique à Chrome13, FF6, Opera11 et IE9. La vérification d'autres navigateurs et versions reste un exercice pour le lecteur.
Note: Comme l' a souligné CMS , pour certains cas d'objets tels que Number
, Boolean
et ceux personnalisés , l' +
opérateur ne produit pas nécessairement un résultat de chaîne. Il peut varier en fonction de l'implémentation de la conversion d'objet en primitif. Par exemple, var o = { valueOf:function () { return 4; } };
évaluer les o + 2;
produits 6
, a number
, évaluer les o + '2'
produits '42'
, a string
.
Pour voir comment le tableau de synthèse a été généré, visitez http://jsfiddle.net/1obxuc7m/
L' +
opérateur de JavaScript a deux objectifs: ajouter deux nombres ou joindre deux chaînes. Il n'a pas de comportement spécifique pour les tableaux, il les convertit donc en chaînes, puis les joint.
Si vous souhaitez joindre deux tableaux pour en produire un nouveau, utilisez plutôt la .concat
méthode :
[1, 2].concat([3, 4]) // [1, 2, 3, 4]
Si vous souhaitez ajouter efficacement tous les éléments d'un tableau à un autre, vous devez utiliser la méthode .push :
var data = [1, 2];
// ES6+:
data.push(...[3, 4]);
// or legacy:
Array.prototype.push.apply(data, [3, 4]);
// data is now [1, 2, 3, 4]
Le comportement de l' +
opérateur est défini dans ECMA-262 5e Section 11.6.1 :
11.6.1 L'opérateur Addition (+)
L'opérateur d'addition effectue une concaténation de chaînes ou une addition numérique. La production
AdditiveExpression : AdditiveExpression + MultiplicativeExpression
est évaluée comme suit:
- Soit
lref
le résultat de l'évaluationAdditiveExpression
.- Laissez -
lval
êtreGetValue(lref)
.- Soit
rref
le résultat de l'évaluationMultiplicativeExpression
.- Laissez -
rval
êtreGetValue(rref)
.- Laissez -
lprim
êtreToPrimitive(lval)
.- Laissez -
rprim
êtreToPrimitive(rval)
.- Si
Type(lprim)
estString
ouType(rprim)
estString
, alors
- Renvoie la chaîne résultant de la concaténation
ToString(lprim)
suivie deToString(rprim)
- Renvoie le résultat de l'application de l'opération d'addition à
ToNumber(lprim)
etToNumber(rprim)
. Voir la note ci-dessous 11.6.3.
Vous pouvez voir que chaque opérande est converti ToPrimitive
. En lisant plus loin, nous pouvons trouver que ToPrimitive
convertira toujours les tableaux en chaînes, produisant ce résultat.
Array.prototype.push.apply(data, [3, 4])
au lieu de data.concat([3,4])
?
concat
produit un nouveau tableau, l'appel plus long étend efficacement un tableau existant .
[].push.apply(data, [3,4])
pour un peu moins de verbosité. En outre, cela est garanti résistant aux autres personnes qui modifient la valeur de Array
.
Il ajoute les deux tableaux comme s'il s'agissait de chaînes .
La représentation sous forme de chaîne pour le premier tableau serait "1,2" et la seconde serait "3,4" . Ainsi, lorsque le +
signe est trouvé, il ne peut pas additionner des tableaux, puis les concaténer comme étant des chaînes.
Les +
chaînes de concats, donc il convertit les tableaux en chaînes.
[1,2] + [3,4]
'1,2' + '3,4'
1,23,4
Pour combiner des tableaux, utilisez concat
.
[1,2].concat([3,4])
[1,2,3,4]
En JavaScript, l'opérateur d'addition binaire ( +
) effectue à la fois l'addition numérique et la concaténation de chaînes. Cependant, lorsque son premier argument n'est ni un nombre ni une chaîne, il le convertit en chaîne (d'où " 1,2
"), puis il fait de même avec le second " 3,4
" et les concatène en " 1,23,4
".
Essayez d'utiliser la méthode "concat" des tableaux à la place:
var a = [1, 2];
var b = [3, 4];
a.concat(b) ; // => [1, 2, 3, 4];
Il semble que JavaScript transforme vos tableaux en chaînes et les relie ensemble. Si vous souhaitez ajouter des tuples ensemble, vous devrez utiliser une boucle ou une fonction de carte.
[1,2]+[3,4]
en JavaScript revient à évaluer:
new Array( [1,2] ).toString() + new Array( [3,4] ).toString();
et donc pour résoudre votre problème, le mieux serait d'ajouter deux tableaux en place ou sans créer un nouveau tableau:
var a=[1,2];
var b=[3,4];
a.push.apply(a, b);
Il fait exactement ce que vous lui avez demandé de faire.
Ce que vous ajoutez ensemble, ce sont des références de tableau (que JS convertit en chaînes), pas des nombres comme il semble. C'est un peu comme ajouter des chaînes ensemble: "hello " + "world"
="hello world"
ce serait bien si vous pouviez surcharger les opérateurs en JavaScript mais vous ne pouvez pas: Puis-je définir des surcharges d'opérateur personnalisées en Javascript? vous ne pouvez pirater que l'opérateur "==" qui convertit en chaînes avant de comparer: http://blogger.xs4all.nl/peterned/archive/2009/04/01/462517.aspx
C'est parce que, l'opérateur + suppose que les opérandes sont des chaînes, s'ils ne sont pas des nombres. Donc, il les convertit d'abord en chaîne et en concats pour donner le résultat final, si ce n'est pas un nombre. En outre, il ne prend pas en charge les tableaux.
Certaines réponses ici ont expliqué comment la sortie indésirable inattendue ('1,23,4'
) se produit et certaines ont expliqué comment obtenir ce qu'elles supposent être la sortie souhaitée ( [1,2,3,4]
) attendue , c'est-à-dire la concaténation de tableaux. Cependant, la nature de la sortie souhaitée attendue est en fait quelque peu ambiguë car la question d'origine indique simplement "Je voulais ajouter les éléments d'un tableau dans un autre ...". Cela pourrait signifier la concaténation de tableau mais cela pourrait aussi signifier l'ajout de tuple (par exemple ici et ici ), c'est-à-dire en ajoutant les valeurs scalaires des éléments d'un tableau aux valeurs scalaires des éléments correspondants dans le second, par exemple en combinant [1,2]
et [3,4]
en obtenant [4,6]
.
En supposant que les deux tableaux ont la même arité / longueur, voici une solution simple:
const arr1 = [1, 2];
const arr2 = [3, 4];
const add = (a1, a2) => a1.map((e, i) => e + a2[i]);
console.log(add(arr1, arr2)); // ==> [4, 6]
Un autre résultat utilisant simplement un simple signe "+" sera:
[1,2]+','+[3,4] === [1,2,3,4]
Donc, quelque chose comme ça devrait fonctionner (mais!):
var a=[1,2];
var b=[3,4];
a=a+','+b; // [1,2,3,4]
... mais il convertira la variable a d'un tableau en chaîne! Garde le en mémoire.