2012-08-13 23 views
28

Duplicar posible:
What is the explanation for these bizarre JavaScript behaviours mentioned in the 'Wat' talk for CodeMash 2012?¿Por qué {} + [] devuelve 0 en Javascript?

Sé que cuando [] se fuerza a una cadena que devuelve la cadena vacía (""), y cuando {} se fuerza a una cadena que devuelve "[object Object]" .

Cuando corro [] + {} en la consola JavaScript del navegador, devuelve lo que cabe esperar:

>> [] + {} 
"[object Object]" 

Pero cuando corro {} + [], devuelve un valor completamente inesperado:

>> {} + [] 
0 

¿Qué podría estar causando que regrese 0?

+0

Parece que está agregando nulo a nulo. Esto sería equivalente a 0 + 0. Eso es solo una suposición. – Trisped

+4

@Trisped: ninguno de esos son nulos. – SLaks

+2

Esta pregunta es subsumida por http://stackoverflow.com/questions/9032856/what-is-the-explanation-for-these-bizarre-javascript-behaviours-mentioned-in-the (que a partir de ahora tiene 301 votos) ..... –

Respuesta

49

Cuando hay un { al comienzo de un comunicado, se interpreta como un bloque, que puede contener cero o más declaraciones wi un bloque. th ninguna declaración en ella tendrá un valor de continuación vacío.

En otras palabras, en este caso, {} se interpreta como un bloque de código vacío.

La instrucción finaliza después de la llave de finalización }, lo que significa que los siguientes tres caracteres +[] comprenden una declaración propia.

Al comienzo de una expresión o instrucción, + es el operador unario plus, que fuerza su operando a un número.

Así +[] es lo mismo que Number([]), que evalúa a 0.

En resumen, es un bloque de código vacío seguido de una matriz forzada a un número.


Dicho todo esto, si se evalúa {} + []dentro de una expresión, devolverá lo que espera:

>> ({} + []) 
"[object Object]" 

Otra cosa interesante es que no se puede empezar una declaración con un objeto literal porque el intérprete intentará analizarlo como una declaración.Haciendo esto

{ "object": "literal" }; 

lanzará un error de sintaxis.

+4

Curiosamente, un objeto literal con una sola propiedad no es un error de sintaxis al comienzo de una declaración si te sales de las citas en el nombre de la propiedad. Simplemente no significa lo que parece que hace. Por ejemplo, '{object:" literal "}' se interpreta como una instrucción de bloque con una sola instrucción, '" literal "'. 'object' se convierte en una etiqueta para la declaración. –

+0

@MatthewCrumley Esto se debe a que 'object:' se trata como una etiqueta (las que se pueden usar con sentencias de interrupción) –

18

Porque el {} se trata como un bloque. Por lo tanto su estado de cuenta es en realidad:

{ 

//empty block here 
} 

+[] //0 same as Number([]) 

Esto es por qué esto es javascript no válido:

eval('{hello: "world", key: "value"}') //Syntax error 

Usted puede agregar() para que sea una expresión (bloques no se pueden utilizar en una expresión por lo que será inicializador de objeto:

eval('({hello: "world", key: "value"})') //Object 
+2

No me resulta inmediatamente obvio cuál es el problema con esta respuesta, así que explique el voto a la baja. – Esailija

+2

+1 para compensar el voto a la baja ... Estuviste unos 25 segundos antes, y creo que tu ejemplo de líneas múltiples es mucho más claro – Izkata

2

El bloque vacío se coacciona en un cero. Luego, el operador + decide forzar el [] a un número.

+0

El bloque vacío es un bloque vacío, no se lo coacciona a nada. – alex

+0

@alex, tiene razón, después de leer la respuesta de Peter Olsen, entiendo que la única coerción es la matriz en un número y el primer conjunto de corchetes simplemente se ignora, se devuelve la última declaración –

Cuestiones relacionadas