javascript - operator - thymeleaf th with
¿Por qué y cómo([![]]+[][[]])[+!+[]+[+[]]] Evalúan a la letra "i"? (2)
Tu parte críptica no es tan críptica si la reescribes un poco:
[]['''']
[] se forzará en una cadena porque no es un número entero, por lo que está buscando una propiedad de [] con el nombre '''' (una cadena vacía). Te quedarás undefined , ya que no hay ninguna propiedad con ese nombre.
En cuanto a la letra real, divide la expresión en los dos componentes principales:
- La cadena
([![]]+[][[]]):-
[![]]es[false]. -
[][[]]undefinedestáundefined. -
"falseundefined"y obtendrá"falseundefined".
-
- Y el índice:
[+!+[]+[+[]]]. Algunos espacios en blanco y paréntesis harán las operaciones mucho más claras:[+(!(+[])) + [+[]]]:-
[+[]]es[0]. -
+[]fuerza[]a un entero, por lo que obtienes0. -
!+[]coacciona0a un booleano y lo niega, por lo que se vuelvetrue. -
+!+[]coercetruea un entero, por lo que obtienes1. - Agrégalos juntos, y obtienes
["10"].
-
Cuando se usa una cadena para acceder a las propiedades de la matriz y la secuencia pasa a ser un elemento de la matriz, la cadena se fuerza en un entero y se recupera el elemento real de la matriz:
> [1, 2, 3]["0"]
1
> [1, 2, 3]["1"]
2
Entonces tu resultado final es:
> "falseundefined"["10"]
"i"
Lea esta respuesta para obtener una explicación de la parte [false] + undefined .
Esta pregunta ya tiene una respuesta aquí:
- ¿Por qué ++ [[]] [+ []] + [+ []] devuelve la cadena "10"? 8 respuestas
- (! [] + []) [+ []] ... Explica por qué funciona 1 respuesta
Mientras leía este artículo publicado en dzone , encontré un fragmento de JavaScript publicado originalmente en Twitter por Marcus Lagergren .
El siguiente código aparentemente imprime la cadena "fail"
(![]+[])[+[]]+(![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]];
Esto implica un tipo de conversión implícita y estoy tratando de entender cómo se interpreta exactamente esta línea.
He aislado cada personaje
-
(![]+[])[+[]]imprime"f" -
(![]+[])[+!+[]]imprime"a" -
([![]]+[][[]])[+!+[]+[+[]]]imprime"i" -
(![]+[])[!+[]+!+[]]imprime"l"
También he logrado analizar las expresiones que devuelven cada letra aparte de "i"
letra "f"
![] una matriz vacía es un Objeto, que según la documentación de ECMAScript, el punto 9.2 se evalúa como true cuando se convierte a boolean por lo que es false
false+[] según el punto 11.6.1 ambos argumentos del operador binario + se convierten a cadena, por lo tanto obtenemos "false"+"" , que evalúa "false"
+[] un operador unario plus causa una conversión de ToNumber seguida de una conversión ToPrimitive si el argumento es un Object . El resultado de dicha conversión se determina llamando al método interno [[DefaultValue]] del objeto. En el caso de una matriz vacía, su valor predeterminado es 0 . (Documentación ECMAScript, secciones: 11.4.6 , 9.3 , 9.1 )
"false"[0] estamos accediendo al personaje en el índice 0 , de ahí la "f"
letra "a"
La misma historia, la única diferencia aquí son las conversiones adicionales en la parte entre corchetes (que evalúa un número para apuntar a otro carácter en la cadena "false" ), desencadenado por el uso de unario + y ! operadores.
+[] evalúa a 0 , como se explicó anteriormente.
!0 evalúa a true como se define en la Sección 9.2 y la Sección 11.4.9 . Primero, 0 se convierte en un booleano false y luego el operador invierte el valor.
+true nuevo, el más ToNumber desencadena una conversión de ToNumber , que devuelve un 1 para binario true ( 11.4.6 y 9.3 )
"false"[1] devuelve el segundo carácter en la cadena, que es "a"
letra "l"
!+[] evalúa como true como se explicó anteriormente
true+true con las primitivas binarias + ToNumber desencadena una conversión de ToNumber . En caso de verdadero, su resultado es 1 y 1+1 es igual a 2
"false"[2] - se explica por sí mismo
letra "i"
Lo que me deja perplejo es la letra "i" . Puedo ver que la segunda parte (entre corchetes) evalúa la cadena "10" y que la primera parte (entre paréntesis) devuelve "falseundefined" pero no puedo entender cómo está sucediendo esto. ¿Podría alguien explicarlo paso a paso? Especialmente la magia que ocurre con corchetes? (matrices y acceso a la matriz)
Si es posible, me gustaría que cada paso contenga un enlace a las reglas subyacentes de ECMAScript.
Lo que encuentro más críptico es esta parte: [][[]]
([![]]+[][[]])[+!+[]+[+[]]] tiene dos partes:
([![]]+[][[]]) y el otro que encontraste tú mismo.
![] devuelve false . Luego usamos [...] para obtener el comportamiento .toString() de + . ( []+[] es lo mismo que [].toString()+[].toString() ) el [][[]] no está definido porque estamos tratando de acceder al índice [] (o [].toString() , que es '''' ) de [] que no está definido.
Perdón por la respuesta anterior, leí totalmente tu comentario.