2012-10-05 19 views
13

Como ya sabrá, ECMAscript intenta ser inteligente e insertará automáticamente los puntos y coma si no los escribió explícitamente. El ejemplo simpleDeclaraciones automáticas de inserción y devolución de punto y coma

function foo() { 
    var bar = 5 

    return bar 
} 

seguirá funcionando como se esperaba. Pero hay algunas advertencias si confías en eso. Si volvemos a escribir esa función como tal

function foo() { 
    var bar = 5 

    return 
    { 
     bar: bar 
    } 
} 

..que función sería ahora volver undefined porque el intérprete insertaría que coma justo después de la declaración return (que es una razón por la que siempre debe llevar llaves en el mismo línea como una declaración).

Sin embargo, sabiendo todo esto me pregunto ahora cómo segura una declaración como la siguiente return es, en todos los navegadores y versiones

function foo() { 
    var a = true, 
     b = true, 
     c = false; 

    return a 
      && b 
      && c; 
} 

acabo escribió un return statement similares en un entorno de producción. Solo porque sabía sobre los "problemas" con ECMAscript beeing no tan inteligente sobre la inserción de punto y coma me pregunto ahora, si ese código funciona al 100%. En mis primeras pruebas en FF/Chrome/IE (últimas versiones), esto parece estar totalmente bien, ¿pero realmente es así?

¿La inserción de punto y coma automática "despertar" si hay algo más que la declaración return en esa línea? ¿Alguien puede proporcionar detalles a nivel de implementación sobre esto?

+1

posiblemente mejor duplicado: [¿Por qué los resultados varían en función de la colocación de la llave?] (Http://stackoverflow.com/q/3641519/1048572) – Bergi

Respuesta

10

El intérprete de Javascript/compilador es tan inteligente para insertar solamente un punto y coma automáticas si después no es válida Javascript.

Su código funciona, porque && b tal y como está hay una expresión válida - por eso hay punto y coma se inserta después de la return a lo que resulta en:

return a && b && c; 

Sin embargo:

return (undefined);//implicitely inserted 
{ 
    .... 
} 

es perfectamente válido y por eso se inserta un punto y coma.

Para completarlo que el árbitro la especificación: automatic semicolon insertion. Vale la pena leer los ejemplos.

+0

Gracias por la respuesta - Ya encontré esa sección de la especificación, Sin embargo, todavía me pregunto qué tan buena/correcta fue esa sección en particular implementada para navegadores (móviles) y versiones, y si podemos confiar al 100% en ese comportamiento. – jAndy

+0

Existen algunos navegadores móviles pequeños que solo admiten un subconjunto limitado de ecmascript, pero en su mayoría son funciones especiales. Sin embargo, estoy bastante seguro de que estas partes "básicas" de la especificación se implementan de manera bastante uniforme en todos los navegadores. – Christoph

+1

Al menos en Chrome, la afirmación * El intérprete/compilador de javascript es tan inteligente que solo inserta punto y coma automático si después hay un código JavaScript válido. * Es falso. Por ejemplo, tome el ejemplo de OP y ajuste la clave 'barra' entre comillas para que se lea''bar'. Ahora, con el corsé abierto en la misma línea que el regreso, todo funciona; con el salto de línea intercalado, la inserción automática de punto y coma crea un error de sintaxis. –

0

Su instrucción de retorno funcionará correctamente en todos los navegadores, como señala Christoph. Yo prefiero que sea aún más explícito, si no fuera por los ordenadores, pero para los seres humanos, al menos, colocando el y los operadores de forma diferente:

return a && 
     b && 
     c; 

En este caso no se necesita pasar un segundo preguntándose si punto y coma automáticos va a causar estragos. Solo prefiero esto para JavaScript, su código original es más fácil de leer.

2

No es necesario navegador/implentation, pero Section 7.9 Automatic Semicolon Insertion del ECMAScript Language Specification es una lectura.

7.9 Punto y coma automática de inserción

Algunas de las declaraciones de ECMAScript (declaración vacía, Sentencia de variable, declaración de la expresión, do-while declaración, continuar declaración, declaración de la rotura, instrucción de retorno, y la instrucción throw) debe ser terminado con punto y coma. Tales puntos y comas siempre pueden aparecer de forma explícita en el texto fuente. Para la conveniencia de , sin embargo, tales puntos y comas pueden omitirse del texto fuente en ciertas situaciones. Estas situaciones se describen diciendo que los puntos y comas se insertan automáticamente en el código fuente token en esas situaciones.

7.9.1 Reglas de inserción automática y coma Hay tres reglas básicas de la inserción punto y coma:

  1. Cuando, ya que el programa se analiza de izquierda a derecha, una muestra (llamado el token infractor) se encontrado que no está permitido por cualquier producción de la gramática, a continuación, un punto y coma se inserta automáticamente antes de que el contador infractor si una o más de las siguientes condiciones es verdadera:

    • el offe nding token está separado del token anterior por al menos un LineTerminator.
    • El token ofensor es}.
  2. Cuando, ya que el programa se analiza de izquierda a derecha, al final de la secuencia de entrada de fichas se encuentra y el analizador no puede analizar el flujo de token de entrada como un solo programa de ECMAScript completa, entonces un punto y coma se inserta automáticamente al final de la secuencia de entrada.

  3. Cuando, ya que el programa se analiza de izquierda a derecha, se encuentra una señal de que esté permitida por alguna producción de la gramática, pero la producción es una producción restringida y el token sería el primer token para una ¿terminal o no terminal inmediatamente después de la anotación? [no LineTerminator aquí]? dentro de la producción restringida (y, por lo tanto, un token se llama token restringido), y el token restringido es separado del token anterior por al menos un LineTerminator, luego se inserta un punto y coma automáticamente antes del token restringido. Sin embargo, hay una condición adicional anulante en las reglas anteriores: un punto y coma nunca se inserta automáticamente si el punto y coma se analizaría como una instrucción vacía o si ese punto y coma se convertiría en uno de los dos puntos y comas en el encabezado de declaración (ver 12.6.3). NOTA Las siguientes son las únicas producciones restringidas en la gramática: PostfixExpression: LeftHandSideExpression [no LineTerminator aquí] ++ LeftHandSideExpression [no LineTerminator aquí] - ContinueStatement: continúan [no LineTerminator aquí] Identificador; BreakStatement: break [no LineTerminator aquí] Identificador; ReturnStatement: return [no LineTerminator here] Expresión; ThrowStatement: throw [no LineTerminator here] Expresión; El efecto práctico de estas producciones restringidas es el siguiente: Cuando se encuentra un token ++ o - donde el analizador lo trataría como un operador postfix, y al menos un LineTerminator ocurrió entre el token anterior y el ++ o - token, entonces un punto y coma se inserta automáticamente antes del token ++ o -. Cuando se encuentra un token continuar, romper, devolver o arrojar y se encuentra un LineTerminator antes del el siguiente token, se inserta automáticamente un punto y coma después del token continue, break, return o throw. El consejo práctico resultante para los programadores de ECMAScript es: Un operador postfix ++ o - debe aparecer en la misma línea que su operando. Una expresión en una instrucción return o throw debería comenzar en la misma línea que el token return o throw. Un identificador en una sentencia break o continue debe estar en la misma línea que el token break o continue.

7.9.2 Ejemplos de Automatic Semicolon Inserción

La fuente

{ 1 2 } 3 

no es una sentencia válida en la gramática ECMAScript, incluso con las reglas de inserción de punto y coma automáticas. En contraste, la fuente

{ 1 
2 } 3 

también no es una sentencia ECMAScript válido, sino que se transforma mediante la inserción punto y coma automática en la siguiente:

{ 1 
;2 ;} 3; 

que es una sentencia de ECMAScript válida. La fuente

for (a; b 
) 

no es una sentencia de ECMAScript válida y no se ve alterado por la inserción automática de punto y coma porque se necesita el punto y coma para la cabecera de una instrucción for. La inserción automática de punto y coma nunca inserta uno de los los dos puntos y comas en el encabezado de una instrucción for. La fuente

return 
a + b 

se transforma mediante la inserción punto y coma automática en la siguiente:

return; 
a + b; 

NOTA La expresión a + b no se trata como un valor a ser devuelto por la instrucción de retorno, debido a que un LineTerminator lo separa de la devolución de token. La fuente

a = b 
++c 

se transforma mediante la inserción punto y coma automática en la siguiente:

a = b; 
++c; 

NOTA El token ++ no se trata como un operador de sufijo aplicar a la variable b, porque se produce una LineTerminator entre b y ++. La fuente

if (a > b) 
else c = d 

no es una sentencia de ECMAScript válida y no se ve alterado por la inserción punto y coma automática antes de que el otro modo, a pesar de que no hay producción de la gramática se aplica en ese momento, debido a que un punto y coma inserta automáticamente entonces ser analizado como una declaración vacía. La fuente

a = b + c 
(d + e).print() 

no se transforma mediante la inserción punto y coma automática, porque la expresión parenthesised que comienza la segunda línea puede ser interpretada como una lista de argumentos para una llamada de función:

a = b + c(d + e).print() 

En la circunstancia que una instrucción de asignación debe comenzar con un paréntesis izquierdo, es una buena idea que el programador proporcione un punto y coma explícito al final de la instrucción anterior en lugar de confiar en la inserción automática de punto y coma .

Cuestiones relacionadas