2009-10-02 16 views
15

En Firefox 3.5, escribo esto en la consola de Firebug:JavaScript: {} == false es un SyntaxError?

false=={} // => evals to false 
{}==false // syntax error 

¿Cuál es la explicación para esto?

+19

Su JavaScript ... lidiar con eso. –

+1

Interesante, pero ¿cuál es exactamente el propósito de eso? –

+2

hm, 'falso == {}' evals a 'falso' en mi Firefox 3.5.3 – SilentGhost

Respuesta

41
{ 

en el inicio de una declaración señales de un 'bloque de instrucciones' (ver ECMA-262-3 sección 12.1), que contiene una lista de declaraciones.

} 

finaliza inmediatamente el bloque de instrucciones sin declaraciones. Esta bien. Pero ahora el analizador está buscando la siguiente declaración:

==false 

¿Huh? Esa no es una declaración; error de sintaxis.

¿Para qué son los bloques de declaración?Bueno, usted está escribiendo un bloque de instrucciones cada vez que dices:

if (something) { 
    ... 
} 

JavaScript define estas declaraciones de control de flujo como:

if "(" <expression> ")" <statement> [else <statement>] 

decir. en el formulario de declaración única sin llaves. Luego, le permite usar un bloque de instrucciones en cualquier lugar donde pueda usar una sola instrucción, lo que significa que puede tener if-llaves-muchas-declaraciones. Pero también significa que puede tener un bloque de instrucciones por sí mismo sin ninguna declaración de control de flujo asociada.

Esto no tiene absolutamente ningún propósito práctico. Usted puede verse tentado a pensar que le dio información escondite, pero no:

var a= 1; 
{ 
    var a= 2; 
} 
alert(a); 

... resultados en 2, porque bloques de instrucciones en sí mismas no crear un nuevo ámbito.

JavaScript define el control de flujo y los bloques de instrucciones de esta manera porque C (y otros lenguajes derivados de él) lo hicieron. Sin embargo, esos idiomas no hacían que {} cumplieran doble función como expresión literal de Objeto, por lo que no tenían la ambigüedad que hace de esta otra característica errónea de JS.

Incluso este aspirante literal:

{ 
    a: 1 
} 

es un bloque de instrucciones válidas, porque ‘:’ se usa para indicar una etiqueta en un comunicado. (y 1 es una expresión de expresiones inútiles, con el punto y coma omitido). Las etiquetas son otra característica heredada de C que rara vez se usa en JavaScript. No son totalmente inútiles como los bloques, pero rara vez se necesitan y a menudo se consideran de mal gusto.

(Un literal con dos propiedades causará un error de sintaxis, como literales de objetos usan separadores de coma, pero etiquetados declaraciones deben estar separados por punto y coma.)

Ésta es not the only place donde sintaxis suelta de JavaScript puede tropezar al hacer alguna otra declaración de algo que piensas que es una expresión.

+0

Y ({}) == trabajos falsos. –

+0

¡Sí, y! {} == ¡verdadero también funciona! – glmxndr

+4

sí y huevo!== remolacha también es falso, porque puedes vencer y huevo pero no puedes vencer a una raíz. – Evernoob

11

OK, he estudiado el ECMAScript specification (PDF) y tengo una explicación que analiza el BNF grammar.

fuentes de ECMAScript se analizan empezando con el símbolo principal, llamada Program:

Program: 
    SourceElements 

SourceElements' (recursiva) definición es la siguiente:

SourceElements : 
    SourceElement 
    SourceElements SourceElement 

El, SourceElement se define como:

SourceElement : 
    Statement 
    FunctionDeclaration 

Lo que nos interesa es la sintaxis literal del objeto, por lo que ignoramos FunctionDeclaration y observe el símbolo Declaración:

Statement : 
    Block 
    VariableStatement 
    EmptyStatement 
    ExpressionStatement 
    IfStatement 
    IterationStatement 
    ContinueStatement 
    BreakStatement 
    ReturnStatement 
    WithStatement 
    LabelledStatement 
    SwitchStatement 
    ThrowStatement 
    TryStatement 

No estoy seguro de si los asuntos de orden de listado (esta es la forma en que están en la especificación), pero ... un objeto literal es un ExpressionStatement, sobre el cual las normas dicen lo siguiente (sección 12.4):

Tenga en cuenta que una ExpressionStatement no puede comenzar con una abertura rizado corsé porque eso podría hacer que ambigua con un bloque. Además, un ExpressionStatement no puede comenzar con la palabra clave de la función porque podría hacer que sea ambigua con una FunciónDeclaración.

así que puede haber una expresión al inicio del programa, pero no debe comenzar con una llave de apertura ({). Es por eso que el siguiente OK trabajo:

  • ({} == false);
  • alert({} == false);
  • !{} == false;
+0

-1 No es una respuesta real (... o tal vez no entiendo su punto). Siéntete libre de iluminarme :) – roosteronacid

+0

Tienes toda la razón. Es más bien una solución. Estoy buscando la especificación ECMAScript 3 para encontrar la respuesta real. Yo también soy curioso. –

+0

Aye. Deshice mi voto abajo. – roosteronacid

0

Simplemente decir, {}==false son compilados por el compilador Js a {};==false, por lo que es un error de sintaxis. debe escribir ({})==false y devolverá falso.

Cuestiones relacionadas