alert((![]+[])[+[]]+(![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]);
A saída desse código é: fail
. Por quê?
A propósito (![]+[])[+!+[]] == 'false'[1]
, certo? Mas por quê ![]+[] == "false"
e por quê +!+[] == 1
?
javascript
cdxf
fonte
fonte
(![]+[])[+[]]
é "f" (o primeiro caractere de "falso"),(![]+[])[+!+[]]
é "a", etc.alert(![]+[])
entãoalert(+!+[])
e você verá.Respostas:
Como @Mauricio comentou
(![]+[])[+[]]
é "f" (o primeiro caractere de "false"),(![]+[])[+!+[]])
é "a", etc ...Como funciona?
Vamos examinar o primeiro caractere, 'f':
A primeira parte da expressão - entre parênteses - é composta por
![]+[]
, o primeiro operando do operador Addition é![]
e produziráfalse
, porque um objeto de matriz - como qualquer outra instância de Object - é verdadeiro e aplicando o lógico (!) NÃO unário operador, ele produz o valorfalse
, por exemplo.Depois disso, temos o segundo operando da adição, um Array vazio,,
[]
isso é feito apenas para converter ofalse
valor para String, pois a representação em string de um array vazio é apenas uma string vazia, equivale a:A última parte, o par de colchetes após os parênteses, eles são os acessadores da propriedade e recebem uma expressão, que é formada pelo Operador Unário Plus aplicado novamente a um array vazio.
O que o Operador Unário Plus faz é a conversão de tipo
Number
, por exemplo:Mais uma vez, isso é aplicado a um Array vazio e, como eu disse antes, a representação em String de um Array é uma string vazia e, quando você converte uma string vazia em Número, ela é convertida em zero:
Portanto, podemos "decodificar" a expressão em algumas etapas:
Observe que o acesso a caracteres usando a notação de colchetes em valores de String não fazia parte do ECMAScript 3rd. Especificação da edição, (é por isso que o
charAt
método existia).Porém este tipo de "propriedades de índice" que representam os caracteres de uma string foram padronizados no ECMAScript 5, e mesmo antes da padronização o recurso estava disponível em um bom número de navegadores (até mesmo no IE8 (modo padrão)).
fonte
int
tipo de dados na linguagem, na verdade todos os números são no formato de dupla precisão de 64 bits (valores IEEE 754), embora alguns operadores trabalhem internamente com valores inteiros (como os operadores bit a bit), o resultado é sempre um duplo . O'i'
vem neste exemplo deundefined
, mas poderia vir,Infinity
por exemplo:(+!+[]/+[+[]]+[])[!+[]+!+[]+!+[]]
=>(1/0+'')[3]
=>(Infinity+'')[3]
=>'i'
"falseundefined"
(construído usando[![]]+[][[]]
:) em que o índice de "i" é 10.+!+[]+[+[]]
dá"10"
. Isso é usado para extrair o "i" (índices de string podem ser usados em javascript se eles puderem ser convertidos em inteiros aparentemente). A construção final que o produz é:([![]]+[][[]])[+!+[]+[+[]]]