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]
. -
[][[]]
undefined
está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
. -
!+[]
coacciona0
a un booleano y lo niega, por lo que se vuelvetrue
. -
+!+[]
coercetrue
a 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.