¿Por qué ++ [[]] [+ []] + [+ []] devuelve la cadena “10”?

1714
SapuSeven 2011-08-26 22:46.

Esto es válido y devuelve la cadena "10"en JavaScript ( más ejemplos aquí ):

console.log(++[[]][+[]]+[+[]])

¿Por qué? ¿Que está sucediendo aquí?

9 answers

2115
pimvdb 2011-08-26 22:56.

Si lo dividimos, el lío es igual a:

++[[]][+[]]
+
[+[]]

En JavaScript, es cierto que +[] === 0. +convierte algo en un número y, en este caso, se reducirá a +""o 0(consulte los detalles de la especificación a continuación).

Por lo tanto, podemos simplificarlo ( ++tiene precedencia sobre +):

++[[]][0]
+
[0]

Porque [[]][0]significa: obtener el primer elemento de [[]], es cierto que:

[[]][0]devuelve la matriz interna ( []). Debido a las referencias, es incorrecto decirlo [[]][0] === [], pero llamemos a la matriz interna Apara evitar la notación incorrecta.

++antes de su operando significa "incrementar en uno y devolver el resultado incrementado". Entonces ++[[]][0]es equivalente a Number(A) + 1(o +A + 1).

Nuevamente, podemos simplificar el desorden en algo más legible. Reemplacemos []por A:

(+[] + 1)
+
[0]

Antes de que +[]pueda coaccionar la matriz en el número 0, primero debe coaccionarse en una cadena, que es "", nuevamente. Finalmente, 1se agrega, lo que da como resultado 1.

  • (+[] + 1) === (+"" + 1)
  • (+"" + 1) === (0 + 1)
  • (0 + 1) === 1

Simplifiquémoslo aún más:

1
+
[0]

Además, esto es cierto en JavaScript:, [0] == "0"porque está uniendo una matriz con un elemento. La unión concatenará los elementos separados por ,. Con un elemento, puede deducir que esta lógica dará como resultado el primer elemento en sí.

En este caso, +ve dos operandos: un número y una matriz. Ahora está tratando de obligar a los dos al mismo tipo. Primero, la matriz se convierte en una cadena "0", luego, el número se convierte en una cadena ( "1"). Cadena de número Cadena+=== .

"1" + "0" === "10" // Yay!

Detalles de la especificación para +[]:

Este es un gran laberinto, pero para hacerlo +[], primero se está convirtiendo en una cadena porque eso es lo que +dice:

11.4.6 Operador Unario +

El operador unario + convierte su operando al tipo de Número.

La producción UnaryExpression: + UnaryExpression se evalúa de la siguiente manera:

  1. Sea expr el resultado de evaluar UnaryExpression.

  2. Regrese ToNumber (GetValue (expr)).

ToNumber() dice:

Objeto

Aplicar los siguientes pasos:

  1. Deje que primValue sea ToPrimitive (argumento de entrada, cadena de sugerencias).

  2. Regrese ToString (primValue).

ToPrimitive() dice:

Objeto

Devuelve un valor predeterminado para el objeto. El valor predeterminado de un objeto se recupera llamando al método interno [[DefaultValue]] del objeto, pasando la sugerencia opcional PreferredType. El comportamiento del método interno [[DefaultValue]] está definido por esta especificación para todos los objetos ECMAScript nativos en 8.12.8.

[[DefaultValue]] dice:

8.12.8 [[DefaultValue]] (pista)

Cuando se llama al método interno [[DefaultValue]] de O con hint String, se toman los siguientes pasos:

  1. Sea toString el resultado de llamar al método interno [[Get]] del objeto O con el argumento "toString".

  2. Si IsCallable (toString) es verdadero, entonces,

una. Sea str el resultado de llamar al método interno [[Call]] de toString, con O como este valor y una lista de argumentos vacía.

B. Si str es un valor primitivo, devuelve str.

El .toStringde una matriz dice:

15.4.4.2 Array.prototype.toString ()

Cuando se llama al método toString, se siguen los siguientes pasos:

  1. Sea matriz el resultado de llamar a ToObject en este valor.

  2. Sea func el resultado de llamar al método interno [[Get]] de la matriz con el argumento "join".

  3. Si IsCallable (func) es falso, entonces deje que func sea el método estándar incorporado Object.prototype.toString (15.2.4.2).

  4. Devuelve el resultado de llamar al método interno [[Call]] de func proporcionando una matriz como este valor y una lista de argumentos vacía.

Así que +[]se reduce a +""porque [].join() === "".

Nuevamente, +se define como:

11.4.6 Operador Unario +

El operador unario + convierte su operando al tipo de Número.

La producción UnaryExpression: + UnaryExpression se evalúa de la siguiente manera:

  1. Sea expr el resultado de evaluar UnaryExpression.

  2. Regrese ToNumber (GetValue (expr)).

ToNumberse define ""como:

El MV de StringNumericLiteral ::: [vacío] es 0.

Así +"" === 0y así +[] === 0.

125
Shef 2011-08-26 22:58.
++[[]][+[]] => 1 // [+[]] = [0], ++0 = 1
[+[]] => [0]

Entonces tenemos una concatenación de cadenas

1+[0].toString() = 10
65
Tim Down 2011-09-15 03:54.

Lo siguiente es una adaptación de una publicación de blog que responde a esta pregunta que publiqué mientras esta pregunta aún estaba cerrada. Los enlaces son a (una copia HTML de) la especificación ECMAScript 3, que sigue siendo la línea de base para JavaScript en los navegadores web de uso común en la actualidad.

Primero, un comentario: este tipo de expresión nunca aparecerá en ningún entorno de producción (sano) y solo sirve como ejercicio para determinar qué tan bien el lector conoce los aspectos sucios de JavaScript. El principio general de que los operadores de JavaScript convierten implícitamente entre tipos es útil, al igual que algunas de las conversiones comunes, pero muchos de los detalles en este caso no lo son.

La expresión ++[[]][+[]]+[+[]]inicialmente puede parecer bastante imponente y oscura, pero en realidad es relativamente fácil dividirla en expresiones separadas. A continuación, simplemente agregué paréntesis para mayor claridad; Puedo asegurarle que no cambian nada, pero si desea verificarlo, no dude en leer sobre el operador de agrupación . Entonces, la expresión se puede escribir más claramente como

( ++[[]][+[]] ) + ( [+[]] )

Desglosando esto, podemos simplificar observando que +[]evalúa a 0. Para satisfacer mismo por qué esto es cierto, revisar el operador unario + y seguir el rastro ligeramente tortuoso que termina con ToPrimitive convertir la matriz vacía en una cadena vacía, que luego se convierte finalmente a 0por ToNumber . Ahora podemos sustituir 0cada instancia de +[]:

( ++[[]][0] ) + [0]

Ya es más sencillo. En cuanto a ++[[]][0], esa es una combinación del operador de incremento de prefijo ( ++), un literal de matriz que define una matriz con un solo elemento que es en sí mismo una matriz vacía ( [[]]) y un descriptor de acceso de propiedad ( [0]) llamado en la matriz definida por el literal de matriz.

Entonces, podemos simplificar [[]][0]a solo []y lo tenemos ++[], ¿verdad? De hecho, este no es el caso porque la evaluación ++[]arroja un error, que inicialmente puede parecer confuso. Sin embargo, un poco de reflexión sobre la naturaleza de ++deja esto claro: se usa para incrementar una variable (por ejemplo ++i) o una propiedad de objeto (por ejemplo ++obj.count). No solo evalúa un valor, sino que también almacena ese valor en algún lugar. En el caso de ++[], no tiene dónde poner el nuevo valor (cualquiera que sea) porque no hay ninguna referencia a una propiedad o variable del objeto para actualizar. En términos de especificaciones, esto está cubierto por la operación interna PutValue , a la que llama el operador de incremento de prefijo.

Entonces, ¿qué hace ++[[]][0]? Bueno, con una lógica similar a +[], la matriz interna se convierte en 0y este valor se incrementa en 1para darnos un valor final de 1. El valor de la propiedad 0en la matriz externa se actualiza 1y se evalúa toda la expresión 1.

Esto nos deja con

1 + [0]

... que es un uso simple del operador de suma . Ambos operandos se convierten primero en primitivas y si alguno de los valores primitivos es una cadena, se realiza una concatenación de cadenas; de lo contrario, se realiza una suma numérica. [0]convierte a "0", por lo que se usa la concatenación de cadenas, produciendo "10".

Como comentario final, algo que puede no ser evidente de inmediato es que anular uno de los métodos toString()o cambiará el resultado de la expresión, porque ambos se verifican y se usan si están presentes al convertir un objeto en un valor primitivo. Por ejemplo, lo siguientevalueOf()Array.prototype

Array.prototype.toString = function() {
  return "foo";
};
++[[]][+[]]+[+[]]

... produce "NaNfoo". Por qué sucede esto se deja como ejercicio para el lector ...

26
renatoluna 2011-12-31 05:41.

Hagámoslo simple:

++[[]][+[]]+[+[]] = "10"

var a = [[]][+[]];
var b = [+[]];

// so a == [] and b == [0]

++a;

// then a == 1 and b is still that array [0]
// when you sum the var a and an array, it will sum b as a string just like that:

1 + "0" = "10"
14
Vlad Shlosberg 2011-12-29 13:13.

Este se evalúa igual pero un poco más pequeño

+!![]+''+(+[])
  • [] - es una matriz que se convierte que se convierte a 0 cuando se le suma o se le resta, por lo tanto + [] = 0
  • ! [] - se evalúa como falso, por lo tanto !! [] se evalúa como verdadero
  • + !! [] - convierte el verdadero en un valor numérico que se evalúa como verdadero, por lo que en este caso 1
  • + '': agrega una cadena vacía a la expresión, lo que hace que el número se convierta en cadena
  • + [] - evalúa a 0

por lo que se evalúa a

+(true) + '' + (0)
1 + '' + 0
"10"

Así que ahora lo tienes, prueba este:

_=$=+[],++_+''+$
7
Eskat0n 2011-08-26 22:58.

+ [] evalúa a 0 [...] luego sumando (+ operación) con cualquier cosa convierte el contenido de la matriz en su representación de cadena que consiste en elementos unidos con una coma.

Cualquier otra cosa como tomar el índice de la matriz (tener mayor prioridad que + operación) es ordinal y no es nada interesante.

4
AsyncMind 2013-06-19 22:19.

Quizás las formas más cortas posibles de evaluar una expresión en "10" sin dígitos son:

+!+[] + [+[]] // "10"

-~[] + [+[]] // "10"

// ========== Explicación ========== \\

+!+[]: +[]Convierte a 0. !0convierte a true. +trueconvierte a 1. -~[]= -(-1)que es 1

[+[]]: +[]Convierte a 0. [0]es una matriz con un solo elemento 0.

Entonces JS evalúa la expresión 1 + [0], por lo tanto Number + Array. Entonces la especificación ECMA funciona: el +operador convierte ambos operandos en una cadena llamando a las toString()/valueOf()funciones desde el Objectprototipo base . Opera como una función aditiva si ambos operandos de una expresión son solo números. El truco es que las matrices convierten fácilmente sus elementos en una representación de cadena concatenada.

Algunos ejemplos:

1 + {} //    "1[object Object]"
1 + [] //    "1"
1 + new Date() //    "1Wed Jun 19 2013 12:13:25 GMT+0400 (Caucasus Standard Time)"

Hay una buena excepción en la que dos Objectssumas dan como resultado NaN:

[] + []   //    ""
[1] + [2] //    "12"
{} + {}   //    NaN
{a:1} + {b:2}     //    NaN
[1, {}] + [2, {}] //    "1,[object Object]2,[object Object]"
3
Alireza 2019-01-19 14:32.

Paso a paso, +convierta el valor en un número y si agrega a una matriz vacía +[]... ya que está vacía y es igual a 0, lo hará

Entonces, a partir de ahí, ahora mire su código, es ++[[]][+[]]+[+[]]...

Y hay un plus entre ellos ++[[]][+[]]+[+[]]

Entonces estos [+[]]regresarán [0]ya que tienen una matriz vacía que se convierte 0dentro de la otra matriz ...

Entonces, como imagina, el primer valor es una matriz bidimensional con una matriz dentro ... por [[]][+[]]lo que será igual a [[]][0]lo que devolverá []...

Y al final ++convertirlo y aumentarlo a 1...

Así que puedes imaginar, 1+ "0"será "10"...

1
Praveen Vedanth 2011-12-30 22:10.
  1. Unario más la cadena dada se convierte en número
  2. La cadena dada por el operador de incremento se convierte e incrementa en 1
  3. [] == ''. Cuerda vacía
  4. + '' o + [] evalúa 0.

    ++[[]][+[]]+[+[]] = 10 
    ++[''][0] + [0] : First part is gives zeroth element of the array which is empty string 
    1+0 
    10
    

Related questions

MORE COOL STUFF

La estrella de HGTV, Christina Hall, revela que tiene 'envenenamiento por mercurio y plomo' probablemente por voltear 'casas asquerosas'

La estrella de HGTV, Christina Hall, revela que tiene 'envenenamiento por mercurio y plomo' probablemente por voltear 'casas asquerosas'

La estrella de HGTV, Christina Hall, revela que le diagnosticaron envenenamiento por mercurio y plomo, probablemente debido a su trabajo como manipuladora de casas.

La estrella de 'Love Is Blind' Brennon Lemieux responde a los cargos de violencia doméstica

La estrella de 'Love Is Blind' Brennon Lemieux responde a los cargos de violencia doméstica

Recientemente salió a la luz un informe policial que acusa a la estrella de 'Love Is Blind', Brennon, de violencia doméstica. Ahora, Brennon ha respondido a los reclamos.

Wynonna Judd se dio cuenta de que ahora es la matriarca de la familia Judd en un momento festivo de pánico

Wynonna Judd se dio cuenta de que ahora es la matriarca de la familia Judd en un momento festivo de pánico

Conozca cómo Wynonna Judd se dio cuenta de que ahora es la matriarca de la familia mientras organizaba la primera celebración de Acción de Gracias desde que murió su madre, Naomi Judd.

Experto en lenguaje corporal explica los 'paralelos' entre Kate Middleton y la princesa Diana

Experto en lenguaje corporal explica los 'paralelos' entre Kate Middleton y la princesa Diana

Descubra por qué un destacado experto en lenguaje corporal cree que es fácil trazar "tales paralelismos" entre la princesa Kate Middleton y la princesa Diana.

Los láseres arrojan luz sobre por qué necesita cerrar la tapa antes de descargar

Los láseres arrojan luz sobre por qué necesita cerrar la tapa antes de descargar

Los inodoros arrojan columnas de aerosol invisibles con cada descarga. ¿Como sabemos? La prueba fue capturada por láseres de alta potencia.

The Secrets of Airline Travel Quiz

The Secrets of Airline Travel Quiz

Air travel is far more than getting from point A to point B safely. How much do you know about the million little details that go into flying on airplanes?

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

¿Caduca el repelente de insectos?

¿Caduca el repelente de insectos?

¿Sigue siendo efectivo ese lote de repelente de insectos que te quedó del verano pasado? Si es así, ¿por cuánto tiempo?

Se revela la estatua de Godzilla más nueva de Tokio

Se revela la estatua de Godzilla más nueva de Tokio

Anteriormente, Kotaku informó que un hotel Godzilla se estaba abriendo en Tokio este abril. Junto al hotel, estaba programada la aparición de una enorme cabeza de 'Zilla, pero todo lo que hemos visto fueron imágenes conceptuales computarizadas.

El alcalde de Chicago realmente quiere que Elon Musk perfore un túnel debajo de la ciudad

El alcalde de Chicago realmente quiere que Elon Musk perfore un túnel debajo de la ciudad

Foto: Getty Desde que lanzó The Boring Company hace un año, Elon Musk ha mencionado varios sitios de construcción posibles para el negocio de perforación de túneles y ha descartado una vaga referencia a una aprobación gubernamental "verbal" para un túnel Hyperloop que conecta la ciudad de Nueva York y Washington. , CC. Pero ahora sabemos que al menos un alcalde quiere que Musk perfore un agujero debajo de su ciudad.

Ponle una tapa. En realidad, ponle una tapa a todo. Consigue 12 tapas de cocina elásticas de silicona por $14. [Exclusivo]

Ponle una tapa. En realidad, ponle una tapa a todo. Consigue 12 tapas de cocina elásticas de silicona por $14. [Exclusivo]

Tapas elásticas de silicona de Tomorrow's Kitchen, paquete de 12 | $14 | Amazonas | Código promocional 20OFFKINJALids son básicamente los calcetines de la cocina; siempre perdiéndose, dejando contenedores huérfanos que nunca podrán volver a cerrarse. Pero, ¿y si sus tapas pudieran estirarse y adaptarse a todos los recipientes, ollas, sartenes e incluso frutas en rodajas grandes que sobran? Nunca más tendrás que preocuparte por perder esa tapa tan específica.

Cuéntanos tus mejores trucos de Washington, DC

Cuéntanos tus mejores trucos de Washington, DC

Hemos pirateado algunas ciudades industriales en esta columna, como Los Ángeles y Las Vegas. Ahora es el momento de una ciudad militar-industrial-compleja.

Patinaje artístico de EE. UU. 'frustrado' por falta de decisión final en evento por equipos, pide una decisión justa

Patinaje artístico de EE. UU. 'frustrado' por falta de decisión final en evento por equipos, pide una decisión justa

El equipo está a la espera de las medallas que ganó en los Juegos Olímpicos de Invierno de 2022 en Beijing, ya que se está resolviendo un caso de dopaje que involucra a la patinadora artística rusa Kamila Valieva.

Los compradores de Amazon dicen que duermen 'como un bebé mimado' gracias a estas fundas de almohada de seda que cuestan tan solo $ 10

Los compradores de Amazon dicen que duermen 'como un bebé mimado' gracias a estas fundas de almohada de seda que cuestan tan solo $ 10

Miles de compradores de Amazon recomiendan la funda de almohada de seda Mulberry, y está a la venta en este momento. La funda de almohada de seda viene en varios colores y ayuda a mantener el cabello suave y la piel clara. Compre las fundas de almohada de seda mientras tienen hasta un 46 por ciento de descuento en Amazon

Se busca al corredor de los Bengals Joe Mixon por orden de arresto emitida por presuntamente apuntar con un arma de fuego a una mujer

Se busca al corredor de los Bengals Joe Mixon por orden de arresto emitida por presuntamente apuntar con un arma de fuego a una mujer

El jueves se presentó una denuncia de delito menor amenazante agravado contra Joe Mixon.

Profesor de la Universidad de Purdue arrestado por presuntamente traficar metanfetamina y proponer favores sexuales a mujeres

Profesor de la Universidad de Purdue arrestado por presuntamente traficar metanfetamina y proponer favores sexuales a mujeres

El Departamento de Policía de Lafayette comenzó a investigar a un profesor de la Universidad de Purdue en diciembre después de recibir varias denuncias de un "hombre sospechoso que se acercaba a una mujer".

Concept Drift: el mundo está cambiando demasiado rápido para la IA

Concept Drift: el mundo está cambiando demasiado rápido para la IA

Al igual que el mundo que nos rodea, el lenguaje siempre está cambiando. Mientras que en eras anteriores los cambios en el idioma ocurrían durante años o incluso décadas, ahora pueden ocurrir en cuestión de días o incluso horas.

India me está pateando el culo

India me está pateando el culo

Estoy de vuelta por primera vez en seis años. No puedo decirte cuánto tiempo he estado esperando esto.

ℝ

“And a river went out of Eden to water the garden, and from thence it was parted and became into four heads” Genesis 2:10. ? The heart is located in the middle of the thoracic cavity, pointing eastward.

¿Merrick Garland le ha fallado a Estados Unidos?

Es más de la mitad de la presidencia de Biden. ¿Qué está esperando Merrick Garland?

¿Merrick Garland le ha fallado a Estados Unidos?

Creo, un poco tarde en la vida, en dar oportunidades a la gente. Generosamente.

Language