¿Por qué [1,2] + [3,4] = "1,23,4" en JavaScript?

Resuelto okeen asked hace 13 años • 14 respuestas

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?

okeen avatar Aug 19 '11 23:08 okeen
Aceptado

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 :

  1. Indefinido
  2. Nulo
  3. Booleano
  4. Número
  5. Cadena
  6. Objeto

Tenga en cuenta que, aunque typeof de forma un tanto confusa se devuelve object Null y functionObjetos 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 Arraycon 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")objectNumberBoolean

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;6numbero + '2''42'string

Para ver cómo se generó la tabla de descripción general, visite http://jsfiddle.net/1obxuc7m/

Saul avatar Aug 19 '2011 16:08 Saul

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 .concatmé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 + MultiplicativeExpressionse evalúa de la siguiente manera:

  1. Sea lrefel resultado de evaluar AdditiveExpression.
  2. Permitir . lval_GetValue(lref)
  3. Sea rrefel resultado de evaluar MultiplicativeExpression.
  4. Permitir . rval_GetValue(rref)
  5. Permitir . lprim_ToPrimitive(lval)
  6. Permitir . rprim_ToPrimitive(rval)
  7. Si Type(lprim)es Stringo Type(rprim)es String, entonces
    1. Devuelve la cadena que es el resultado de la concatenación ToString(lprim)seguida deToString(rprim)
  8. Devuelve el resultado de aplicar la operación de suma a ToNumber(lprim)y ToNumber(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 ToPrimitivesiempre convertirá matrices en cadenas, produciendo este resultado.

Jeremy avatar Aug 19 '2011 16:08 Jeremy