javascript semicolon

¿Cuáles son las reglas para la inserción automática de punto y coma(ASI) de JavaScript?



semicolon (4)

Con respecto a la inserción de punto y coma y la declaración var, tenga cuidado de olvidar la coma cuando use var pero que abarque varias líneas. Alguien encontró esto en mi código ayer:

var srcRecords = src.records srcIds = [];

Se ejecutó, pero el efecto fue que la declaración / asignación srcIds era global porque la declaración local con var en la línea anterior ya no se aplicaba, ya que esa declaración se consideraba finalizada debido a la inserción automática del punto y coma.

Bueno, primero debería preguntar si esto depende del navegador.

He leído que si se encuentra un token no válido, pero la sección de código es válida hasta ese token no válido, se inserta un punto y coma antes del token si está precedido por un salto de línea.

Sin embargo, el ejemplo común citado para errores causados ​​por la inserción de punto y coma es:

return _a+b;

..que no parece seguir esta regla, ya que _a sería un token válido.

Por otro lado, romper las cadenas de llamadas funciona como se espera:

$(''#myButton'') .click(function(){alert("Hello!")});

¿Alguien tiene una descripción más detallada de las reglas?


Directamente de la ecma-international.org/publications/standards/Ecma-262.htm :

7.9.1 Reglas de inserción automática de punto y coma

Hay tres reglas básicas de inserción de punto y coma:

  1. Cuando, cuando el programa se analiza de izquierda a derecha, se encuentra un token (llamado token ofensivo ) que no está permitido por ninguna producción de la gramática, entonces se inserta automáticamente un punto y coma antes del token ofensivo si uno o más de los siguientes las condiciones son ciertas
    • El token ofensivo está separado del token anterior por al menos un LineTerminator .
    • El token ofensivo es } .
  2. Cuando, al analizar el programa de izquierda a derecha, se encuentra el final del flujo de entrada de tokens y el analizador no puede analizar el flujo de token de entrada como un único Program ECMAScript completo, luego se inserta automáticamente un punto y coma al final de el flujo de entrada.
  3. Cuando, cuando el programa se analiza de izquierda a derecha, se encuentra un token que es permitido 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 un terminal o no terminal inmediatamente después de la anotación " [no LineTerminator here] " dentro de la producción restringida (y, por lo tanto, tal token se denomina token restringido), y el token restringido está separado del token anterior por al menos un LineTerminator , luego se inserta automáticamente un punto y coma antes del token restringido .

Sin embargo, hay una condición adicional adicional en las reglas anteriores: un punto y coma nunca se inserta automáticamente si el punto y coma se analizaría como una declaración vacía o si ese punto y coma se convertiría en uno de los dos puntos y coma en el encabezado de una declaración for (consulte 12.6.3).


En primer lugar, debe saber qué declaraciones se ven afectadas por la inserción automática de punto y coma (también conocido como ASI por brevedad):

  • declaración vacía
  • declaración var
  • declaración de expresión
  • declaración de do-while
  • continue declaración
  • declaración de break
  • declaración de return
  • throw declaración

Las reglas concretas de ASI se describen en la especificación §11.9.1 Reglas de inserción automática de punto y coma

Se describen tres casos:

  1. Cuando se encuentra un token ( LineTerminator o } ) que no está permitido por la gramática, se inserta un punto y coma antes si:

    • El token está separado del token anterior por al menos un LineTerminator .
    • El token es }

    por ejemplo :

    { 1 2 } 3

    se transforma en

    { 1 ;2 ;} 3;

    El NumericLiteral 1 cumple la primera condición, el siguiente token es un terminador de línea.
    El 2 cumple la segunda condición, el siguiente token es } .

  2. Cuando se encuentra el final del flujo de entrada de tokens y el analizador no puede analizar el flujo de token de entrada como un único programa completo, se inserta automáticamente un punto y coma al final del flujo de entrada.

    por ejemplo :

    a = b ++c

    se transforma en:

    a = b; ++c;

  3. Este caso ocurre cuando se permite un token por parte de la producción de la gramática, pero la producción es una producción restringida , un punto y coma se inserta automáticamente antes del token restringido.

    Producciones restringidas:

    UpdateExpression : LeftHandSideExpression [no LineTerminator here] ++ LeftHandSideExpression [no LineTerminator here] -- ContinueStatement : continue ; continue [no LineTerminator here] LabelIdentifier ; BreakStatement : break ; break [no LineTerminator here] LabelIdentifier ; ReturnStatement : return ; return [no LineTerminator here] Expression ; ThrowStatement : throw [no LineTerminator here] Expression ; ArrowFunction : ArrowParameters [no LineTerminator here] => ConciseBody YieldExpression : yield [no LineTerminator here] * AssignmentExpression yield [no LineTerminator here] AssignmentExpression

    El ejemplo clásico, con el ReturnStatement :

    return "something";

    se transforma en

    return; "something";


No podía entender esas 3 reglas en las especificaciones demasiado bien, espero tener algo que sea más sencillo en inglés, pero esto es lo que he recopilado de JavaScript: The Definitive Guide, 6ta edición, David Flanagan, O''Reilly, 2011:

Citar:

JavaScript no trata todos los saltos de línea como un punto y coma: por lo general, trata los saltos de línea como puntos y coma solo si no puede analizar el código sin los puntos y coma.

Otra cita: para el código.

var a a = 3 console.log(a)

JavaScript no trata el segundo salto de línea como un punto y coma porque puede continuar analizando la instrucción más larga a = 3;

y:

dos excepciones a la regla general de que JavaScript interpreta los saltos de línea como puntos y coma cuando no puede analizar la segunda línea como una continuación de la declaración en la primera línea. La primera excepción involucra las declaraciones de devolución, ruptura y continuación

... Si aparece un salto de línea después de cualquiera de estas palabras ... JavaScript siempre interpretará ese salto de línea como un punto y coma.

... La segunda excepción involucra a los operadores ++ y −− ... Si desea utilizar alguno de estos operadores como operadores de posfijo, deben aparecer en la misma línea que la expresión a la que se aplican. De lo contrario, el salto de línea se tratará como un punto y coma, y ​​el ++ o - se analizará como un operador de prefijo aplicado al código que sigue. Considere este código, por ejemplo:

x ++ y

Se analiza como x; ++y; x; ++y; , no como x++; y x++; y

Así que creo que para simplificarlo, eso significa:

En general, JavaScript lo tratará como una continuación del código siempre y cuando tenga sentido, excepto en 2 casos: (1) después de algunas palabras clave como return , break , continue y (2) si ve ++ o -- en una nueva línea, entonces agregará el ; Al final de la línea anterior.

La parte sobre "tratarlo como una continuación del código, siempre que tenga sentido" lo hace sentir como una coincidencia codiciosa de expresiones regulares.

Con lo dicho anteriormente, eso significa que para el return con un salto de línea, el intérprete de JavaScript insertará un ;

(citado de nuevo: si aparece un salto de línea después de cualquiera de estas palabras [como return ] ... JavaScript siempre interpretará ese salto de línea como un punto y coma)

y por este motivo, el ejemplo clásico de

return { foo: 1 }

no funcionará como se esperaba, porque el intérprete de JavaScript lo tratará como:

return; // returning nothing { foo: 1 }

No debe haber ningún salto de línea inmediatamente después de la return :

return { foo: 1 }

para que funcione correctamente. Y usted puede insertar un ; usted mismo si tuviera que seguir la regla de usar un ; después de cualquier declaración:

return { foo: 1 };