13

Leyendo me encontré esta expresión:

_=$=+[],++_+''+$

curiosamente es una expresión válida en javascript pero lo más curioso es que al ejecutarla, el resultado es:

10

Traté de encontrarle sentido descomponiendo la expresión pero no logré mucho.

¿Por qué el resultado de dicha expresión es igual a 10?

Gepser Hoil
  • 3,463
  • 5
  • 29
  • 58
  • jaja espero ayude var1=var2=+[],++var1+'' +var1+''+5*var1+''+3*var1 – Angel Angel Mar 18 '16 at 06:14
  • por cierto cuantos puntos tienes ? Saludos – Angel Angel Mar 18 '16 at 06:15
  • 1
    Porque JavaScript es una locura. Ejecuta esto: `[] + []`, luego `{} + {}`, luego `[] - []` y por último `{} - {}`. El último de esos 4 lo puedes cambiar por `Array(16).join({} - {}) + " Batman"` para que entiendas por qué JS es una locura total. –  Mar 18 '16 at 14:42
  • Por cierto esta expresión solo funciona cuando no se activa modo estricto. Intenta usando `node --use_strict` y luego escribiendo `_=$=+[],++_+''+$` te dará `Reference Error: $ is not defined` – devconcept Mar 18 '16 at 15:25
  • @LuiggiMendoza Aqui está la respuesta a lo que pones http://stackoverflow.com/questions/9032856/what-is-the-explanation-for-these-bizarre-javascript-behaviours-mentioned-in-the ;) – devconcept Mar 18 '16 at 15:29
  • @devconcept no lo ponía como pregunta. Sí sé lo que sucede. –  Mar 18 '16 at 15:35
  • 1
    @LuiggiMendoza Je, lo sé. Lo escribí para que conste que hasta los comportamientos más raros son "normales" o_0 y están documentados. – devconcept Mar 18 '16 at 15:39

2 Answers2

13

Fácil, esta expresión

_=$=+[],++_+''+$

Puede ser escrita de forma más legible así

_ = $ = +[], ++_ + '' + $

Que puede ser entendida como:

(_ = $ = +[]), (++_ + '' + $)

Que es lo mismo que:

_ = $ = +[];
++_ + '' + $;

Que es lo mismo que:

$ = +[];
_ = $;
++_ + '' + $;

Que para leerlo más fácil podremos renombrar variables como:

var1 = +[];                 // +[] fuerza al empty array a volverse number 0
var2 = var1;                // Ahora var1 y var2 valen 0
++var2 + '' + var1;         // ++var2 === 1, 1 + '' === '1' y '1' + 0 === '10'

Que ejecutándolo paso por paso:

var1 = 0;
var2 = var1;              
++var2 + '' + var1  
...
var2 = 0;              
++var2 + '' + var1;
...
++var2 + '' + 0;       //var2 === 0
...
1 + '' + 0;
...
'1' + 0;
...
'10';
Carlos Muñoz
  • 12,864
  • 2
  • 42
  • 62
5

Hagamos algunas transformaciones. A lo que llama _ voy a llamarlo a y a lo que llama $ voy a llamarlo b. Simplemente cambié el nombre de estas dos variables, por lo que su expresión original ahora es:

a=b=+[],++a+''+b

Bajo esta expresión equivalente:

a =  
   b = + [] 
           , 
             ++a+''+b
  1. El operador con mayor precedencia es el operador , (coma). Este operador evalúa cada uno de sus operandos de izquierda a derecha y retorna el valor de la última expresión que evaluó.
  2. Evalúa la expresión a = b = +[]. Esta expresión es una expresión de asignación compuesta. El operador de asignación = asocia de derecha a izquierda, por lo tanto, esta expresión debe evaluarse como a = (b = +[])
  3. La expresión b = +[] le asigna a una variable b (que debe resolverla primera dentro de la cadena del scope: si existe, le asigna el valor adecuado, si no existe -como en este ejemplo- crea una propiedad llamada b en el objeto global (en el navegador sería el objeto window). A esa variable le asigna el valor +[]. El operador unitario + se encarga de convertir un tipo de dato a un valor entero. En este caso, se intenta convertir el arreglo vacío []. Cuando en un arreglo se usa el operador +, Javascript llama al método toString() del arreglo, devolviendo una representación en cadena de caracteres del contenido del mismo. Como el arreglo está vacío, devuelve la cadena ''. Ahora, el estándar ECMA menciona que la representación de una cadena de texto vacía al convertirla en un número es el valor entero 0, por lo tanto, la expresión b = +[] le asigna a b el valor 0.
  4. Este valor 0 es asignado a la variable a, la cual, al igual que la variable b, si existe, se le asigna el valor, si no, se crea como propiedad en el objeto global. Hasta aquí, lo que se hizo fue crear dos variables llamadas a y b que tienen asignado el valor 0 y que existen en el objeto global.
  5. A continuación se evalúa el segundo operando de la expresión ,: ++a+''+b. Debido a la aparición de la cadena de carácteres vacía ''. los operadores + que aparecen actuarán concatenando cadenas de carácteres. Este operador evalúa de izquierda a derecha.
  6. En primer lugar, evalúa la expresión ++a. Esta expresión contiene el operador de incremento unitario prefijo ++: su labor es aumentar en 1 el valor de la variable y devolver ese resultado. Por lo tanto, a, que es 0, ahora es 1 y retorna este valor.
  7. El operador + concatena el valor obtenido por el operando izquierdo (que devolvió el valor entero 1) con la cadena de carácteres vacía ''. Esta labor promueve el valor entero 0 a la cadena de caracteres '1'. Finalmente retorna este resultado.
  8. El operador + concatena el valor obtenido por el operando izquierdo (que devolvió la cadena de caracteres '1' con el operando derecho. El operando derecho es simplemente el valor de la variable b, que es 0. Nuevamente, el operador + promociona este valor entero a la cadena de caracteres '0', debido a la concatenación. La concatenación del operando izquierdo con el derecho es '1'+ '0' = '10' y devuelve este resultado.
  9. Finalmente, como al comienzo mencioné, el operador , devuelve el resultado que la última expresión devolvió, en este caso, devolverá la cadena de caracteres '10', que es el resultado que usted obtiene.
dwarandae
  • 2,459
  • 6
  • 18
  • 41