¿Por qué [1,2] + [3,4] = "1,23,4" en JavaScript?
Quería agregar los elementos de una matriz a otra, así que intenté esto:
[1,2] + [3,4]
Respondió con:
"1,23,4"
¿Qué está pasando?
El +
operador no está definido para matrices .
Lo que sucede es que Javascript convierte matrices en cadenas y las concatena.
Actualizar
Dado que esta pregunta y, en consecuencia, mi respuesta están recibiendo mucha atención, sentí que también sería útil y relevante tener una descripción general de cómo +
se comporta el operador en general.
Así que aquí va.
Excluyendo E4X y elementos específicos de la implementación, Javascript (a partir de ES5) tiene 6 tipos de datos integrados :
- Indefinido
- Nulo
- Booleano
- Número
- Cadena
- Objeto
Tenga en cuenta que, aunque typeof
de forma un tanto confusa se devuelve object
Null y function
Objetos invocables, Null en realidad no es un Objeto y, estrictamente hablando, en implementaciones de Javascript que cumplen con las especificaciones, todas las funciones se consideran Objetos.
Así es: Javascript no tiene matrices primitivas como tales; sólo instancias de un Objeto llamado Array
con algo de azúcar sintáctico para aliviar el dolor.
Para aumentar aún más la confusión, las entidades contenedoras como y son todas de tipo new Number(5)
, no números, valores booleanos o cadenas como cabría esperar. Sin embargo, para los operadores aritméticos y se comportan como números.new Boolean(true)
new String("abc")
object
Number
Boolean
Fácil, ¿eh? Una vez aclarado todo esto, podemos pasar a la descripción general en sí.
Diferentes tipos de resultados +
por tipos de operandos
|| 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 |
*se aplica a Chrome13, FF6, Opera11 e IE9. La comprobación de otros navegadores y versiones se deja como ejercicio para el lector.
Nota: Como lo señala CMS , para ciertos casos de objetos como y personalizados Number
, el operador no necesariamente produce un resultado de cadena. Puede variar según la implementación de la conversión de objeto a primitiva. Por ejemplo , evaluar produce , a , evaluar produce , a .Boolean
+
var o = { valueOf:function () { return 4; } };
o + 2;
6
number
o + '2'
'42'
string
Para ver cómo se generó la tabla de descripción general, visite http://jsfiddle.net/1obxuc7m/
El operador de JavaScript +
tiene dos propósitos: sumar dos números o unir dos cadenas. No tiene un comportamiento específico para matrices, por lo que las convierte en cadenas y luego las une.
Si desea unir dos matrices para producir una nueva, utilice el .concat
método :
[1, 2].concat([3, 4]) // [1, 2, 3, 4]
Si desea agregar de manera eficiente todos los elementos de una matriz a otra, debe usar el método .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]
El comportamiento del +
operador se define en ECMA-262 5e Sección 11.6.1 :
11.6.1 El operador de suma (+)
El operador de suma realiza una concatenación de cadenas o una suma numérica. La producción
AdditiveExpression : AdditiveExpression + MultiplicativeExpression
se evalúa de la siguiente manera:
- Sea
lref
el resultado de evaluarAdditiveExpression
.- Permitir .
lval
_GetValue(lref)
- Sea
rref
el resultado de evaluarMultiplicativeExpression
.- Permitir .
rval
_GetValue(rref)
- Permitir .
lprim
_ToPrimitive(lval)
- Permitir .
rprim
_ToPrimitive(rval)
- Si
Type(lprim)
esString
oType(rprim)
esString
, entonces
- Devuelve la cadena que es el resultado de la concatenación
ToString(lprim)
seguida deToString(rprim)
- Devuelve el resultado de aplicar la operación de suma a
ToNumber(lprim)
yToNumber(rprim)
. Consulte la nota a continuación 11.6.3.
Puedes ver que cada operando se convierte ToPrimitive
. Al leer más, podemos encontrar que ToPrimitive
siempre convertirá matrices en cadenas, produciendo este resultado.