Volevo aggiungere gli elementi di un array in un altro, quindi ho provato questo:
[1,2] + [3,4]
Ha risposto con:
"1,23,4"
Cosa sta succedendo?
[5,6,7][1,2]
è 7
perché utilizza l'ultimo elemento nel secondo array. Oo
Volevo aggiungere gli elementi di un array in un altro, quindi ho provato questo:
[1,2] + [3,4]
Ha risposto con:
"1,23,4"
Cosa sta succedendo?
[5,6,7][1,2]
è 7
perché utilizza l'ultimo elemento nel secondo array. Oo
Risposte:
L' +
operatore non è definito per le matrici .
Quello che succede è che Javascript converte le matrici in stringhe e le concatena.
Dato che questa domanda e, di conseguenza, la mia risposta stanno suscitando molta attenzione, ho ritenuto utile e pertinente avere una visione d'insieme su come l' +
operatore si comporta anche in generale.
Quindi, eccola qui.
Escludendo E4X e elementi specifici dell'implementazione, Javascript (a partire da ES5) ha 6 tipi di dati integrati :
Si noti che sebbene typeof
restituisca un po 'di confusione object
per Null e function
per oggetti richiamabili, Null in realtà non è un oggetto e in senso stretto, nelle implementazioni Javascript conformi alle specifiche tutte le funzioni sono considerate come oggetti.
Esatto - Javascript non ha matrici primitive come tali; solo le istanze di un Oggetto chiamate Array
con dello zucchero sintattico per alleviare il dolore.
Aggiungendo altro alla confusione, entità wrapper come new Number(5)
, new Boolean(true)
e new String("abc")
sono tutte di object
tipo, non numeri, valori booleani o stringhe come ci si potrebbe aspettare. Tuttavia per gli operatori aritmetici Number
e Boolean
comportarsi come numeri.
Facile, eh? Con tutto ciò, possiamo passare alla panoramica stessa.
Diversi tipi di risultati per tipo di +
operando
|| 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 |
* si applica a Chrome13, FF6, Opera11 e IE9. Il controllo di altri browser e versioni viene lasciato come esercizio per il lettore.
Nota: Come sottolineato da CMS , per alcuni casi di oggetti quali Number
, Boolean
e quelli personalizzati l' +
operatore non deve necessariamente produrre un risultato stringa. Può variare a seconda dell'implementazione della conversione da oggetto a primitiva. Ad esempio, var o = { valueOf:function () { return 4; } };
valutare o + 2;
produce 6
, a number
, valutare o + '2'
produce '42'
, a string
.
Per vedere come è stata generata la tabella di panoramica, visitare http://jsfiddle.net/1obxuc7m/
L' +
operatore JavaScript ha due scopi: aggiungere due numeri o unire due stringhe. Non ha un comportamento specifico per gli array, quindi li sta convertendo in stringhe e poi li unisce.
Se si desidera unire due array per produrne uno nuovo, utilizzare invece il .concat
metodo :
[1, 2].concat([3, 4]) // [1, 2, 3, 4]
Se si desidera aggiungere in modo efficiente tutti gli elementi da un array all'altro, è necessario utilizzare il metodo .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]
Il comportamento +
dell'operatore è definito nella Sezione 11.6.1 dell'ECMA-262 5e :
11.6.1 Operatore aggiunta (+)
L'operatore addizione esegue la concatenazione di stringhe o l'aggiunta numerica. La produzione
AdditiveExpression : AdditiveExpression + MultiplicativeExpression
viene valutata come segue:
- Lascia che
lref
sia il risultato della valutazioneAdditiveExpression
.- Lascia
lval
stareGetValue(lref)
.- Lascia che
rref
sia il risultato della valutazioneMultiplicativeExpression
.- Lascia
rval
stareGetValue(rref)
.- Lascia
lprim
stareToPrimitive(lval)
.- Lascia
rprim
stareToPrimitive(rval)
.- Se
Type(lprim)
èString
oType(rprim)
èString
, allora
- Restituisce la stringa risultante dalla concatenazione
ToString(lprim)
seguita daToString(rprim)
- Restituisce il risultato dell'applicazione dell'operazione di aggiunta a
ToNumber(lprim)
eToNumber(rprim)
. Vedi la nota sotto 11.6.3.
Puoi vedere che ogni operando viene convertito ToPrimitive
. Leggendo ulteriormente possiamo scoprire che ToPrimitive
convertirà sempre le matrici in stringhe, producendo questo risultato.
Array.prototype.push.apply(data, [3, 4])
invece di data.concat([3,4])
?
concat
produce un nuovo array, la chiamata più lunga estende in modo efficiente un array esistente .
[].push.apply(data, [3,4])
per un po 'meno verbosità. Inoltre, questo è garantito per resistere ad altre persone che cambiano il valore di Array
.
Aggiunge i due array come se fossero stringhe .
La rappresentazione di stringa per il primo array sarebbe "1,2" e il secondo sarebbe "3,4" . Quindi, quando +
viene trovato il segno, non può sommare le matrici e quindi concatenarle come stringhe.
Le +
stringhe concats, quindi converte le matrici di stringhe.
[1,2] + [3,4]
'1,2' + '3,4'
1,23,4
Per combinare le matrici, utilizzare concat
.
[1,2].concat([3,4])
[1,2,3,4]
In JavaScript, l'operatore di aggiunta binaria ( +
) esegue sia l'aggiunta numerica sia la concatenazione di stringhe. Tuttavia, quando il suo primo argomento non è né un numero né una stringa, lo converte in una stringa (quindi " 1,2
"), quindi fa lo stesso con il secondo " 3,4
" e li concatena in " 1,23,4
".
Prova invece a utilizzare il metodo "concat" di array:
var a = [1, 2];
var b = [3, 4];
a.concat(b) ; // => [1, 2, 3, 4];
Sembra che JavaScript stia trasformando le tue matrici in stringhe e le unendo insieme. Se si desidera aggiungere insieme le tuple, è necessario utilizzare un ciclo o una funzione della mappa.
[1,2]+[3,4]
in JavaScript equivale a valutare:
new Array( [1,2] ).toString() + new Array( [3,4] ).toString();
e quindi per risolvere il tuo problema, la cosa migliore sarebbe aggiungere due array sul posto o senza creare un nuovo array:
var a=[1,2];
var b=[3,4];
a.push.apply(a, b);
Sta facendo esattamente quello che gli hai chiesto di fare.
Quello che stai sommando sono riferimenti di array (che JS converte in stringhe), non numeri come sembra. È un po 'come aggiungere stringhe insieme: "hello " + "world"
="hello world"
sarebbe bello se potessi sovraccaricare gli operatori in JavaScript ma non puoi: Posso definire sovraccarichi personalizzati degli operatori in Javascript? puoi solo hackerare l'operatore "==" che converte in stringhe prima di confrontare: http://blogger.xs4all.nl/peterned/archive/2009/04/01/462517.aspx
È perché, l'operatore + presuppone che gli operandi siano una stringa, se non sono numeri. Quindi, prima li converte in stringa e si concede per dare il risultato finale, se non è un numero. Inoltre, non supporta gli array.
Alcune risposte qui hanno spiegato come '1,23,4'
avviene l' output indesiderato imprevisto ( ) e alcuni hanno spiegato come ottenere quello che si presume sia l'output desiderato atteso ( [1,2,3,4]
), ovvero la concatenazione di array. Tuttavia, la natura dell'output desiderato atteso è in realtà un po 'ambigua perché la domanda originale afferma semplicemente "Volevo aggiungere gli elementi di un array in un altro ...". Ciò potrebbe significare la concatenazione di array ma potrebbe anche significare l'aggiunta di tuple (ad esempio qui e qui ), vale a dire aggiungere i valori scalari degli elementi in un array ai valori scalari degli elementi corrispondenti nel secondo, ad esempio combinando [1,2]
e [3,4]
ottenere [4,6]
.
Supponendo che entrambi gli array abbiano la stessa arità / lunghezza, ecco una soluzione semplice:
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]