2010-11-13 16 views
92
alert((![]+[])[+[]]+(![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]); 

La salida de este código es: fail. ¿Por qué?(! [] + []) [+ []] ... Explicar por qué esto funciona

Por cierto, (![]+[])[+!+[]] == 'false'[1], ¿no ?. Pero ¿por qué ![]+[] == "false" y por qué +!+[] == 1?

+13

@Snoob no me fío de usted. Al final, es una bomba de tenedor. –

+0

: |. Esto solo es un código js, ​​no puedo lastimarte. – Snoob

+3

Es una cadena literal, por supuesto;) –

Respuesta

116

Como @Mauricio comentó (![]+[])[+[]] es "f" (el primer carácter de "falso"), (![]+[])[+!+[]]) es "A", etc ...

¿Cómo funciona?

Vamos a examinar el primer carácter, 'f':

(![]+[])[+[]]; // 'f' 

La primera parte de la expresión entre paréntesis, está compuesto por ![]+[], el primer operando del operador de adición es ![] y producirá false , porque una matriz de objetos-como cualquier otro objeto de instancia-es Truthy, y aplicando el lógico (!) operador NOT unario, produce el valor false, por ejemplo.

![]; // false, it was truthy 
!{}; // false, it was truthy 
!0; // true, it was falsey 
!NaN; // true, it was falsey 

Tras ello, tenemos el segundo operando de la adición, una matriz vacía, [], esto se hace sólo para convertir el valor false en cadena, porque la representación de cadena de una matriz vacía es simplemente una cadena vacía , es equivalente a:

false+[]; // "false" 
false+''; // "false" 

la última parte, el par de corchetes después de los paréntesis, son la propiedad de acceso, y reciben una expresión, que está formado por la Plus operador unario aplica a una matriz vacía de nuevo.

Lo que hace el Plus operador unitario es la conversión de tipos, a Number, por ejemplo:

typeof +"20"; // "number" 

Una vez más, esto se aplica a un conjunto vacío, y como he dicho antes, la representación de cadena de un array es una cadena vacía, y al convertir una cadena vacía al número, se convierte en cero:

+[]; // 0, because 
+[].toString(); // 0, because 
+""; // 0 

por lo tanto podemos "decodificar" la expresión que en algunos pasos:

(![]+[])[+[]]; 
(false+[])[+[]]; 
(false+'')[+[]]; 
(false+'')[0]; 
('false')[0]; // "f" 

Tenga en cuenta que para acceder a los caracteres utilizando la notación de corchetes en los valores de cadena no era parte de la tercera ECMAScript. Especificación de edición, (es por eso que el método charAt existía).

Sin embargo, este tipo de "propiedades de índice" que representan los caracteres de una cadena se estandarizaron en ECMAScript 5 e incluso antes de la estandarización la característica estaba disponible en un buen número de navegadores (incluso en IE8 (modo estándar)).

+39

Solo espero que esto nunca sea una pregunta de entrevista. – Inisheer

+4

@JTA: ¡Espero que * sea *! Hubiera pasado :-D –

+1

! + [] -> ¿por qué es cierto? – Snoob

Cuestiones relacionadas