601 votes

Quelles sont les règles pour l'insertion automatique des points-virgules (ASI) de Javascript?

Bien, d'abord je dois sans doute te demander si c'est le navigateur dépendante.

J'ai lu que si une défaillance de jeton est trouvé, mais la section de code est valide jusqu'à ce que invalid token, un point-virgule est insérée avant le jeton si elle est précédée par un saut de ligne.
Cependant, l'exemple souvent cité pour les bugs causés par des point-virgules insertion est:

return
  _a+b;

ce qui ne semble pas suivre cette règle, car _a serait un jeton valide. D'autre part, la rupture jusqu'à l'appel des chaînes fonctionne comme prévu:

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

Quelqu'un aurait-il une description plus approfondie des règles?

596voto

CMS Points 315406

Tout d'abord, vous devez savoir quels états sont affectés par le système automatique de point-virgule insertion (aussi connu comme ASI par souci de concision):

  • déclaration vide
  • var déclaration
  • l'expression de déclaration
  • do-while déclaration
  • continue déclaration
  • break déclaration
  • return déclaration
  • throw déclaration

Les règles concrètes de l'ASI, sont décrites dans le cahier des charges:

Trois cas sont décrits:

  1. Lorsqu'un jeton (LineTerminator ou }) est rencontré et qu'il n'est pas autorisé par la grammaire, un point-virgule est insérée avant, si:

    • Le jeton est séparée de la précédente jeton par au moins un LineTerminator.
    • Le jeton est - }

    E. g.:

        { 1
        2 } 3
        // is transformed to
        { 1
        ;2 ;} 3;
    

    L' NumericLiteral 1 satisfait à la première condition, le jeton suivant est un terminateur de ligne. L' 2 répond à la deuxième condition, le jeton suivant est }.

  2. Lorsque la fin du flux d'entrée de jetons est rencontré et de l'analyseur est impossible d'analyser les tokens d'entrée courant d'un seul Programme complet, puis un point-virgule est automatiquement inséré à la fin du flux d'entrée.

    E. g.:

    a = b
    ++c
    // is transformed to:
    a = b;
    ++c;
    
  3. Ce cas se produit lorsqu'un jeton est autorisé par une partie de la production de la grammaire, mais la production est une production restreinte de la production, un point-virgule est automatiquement inséré avant le jeton restreint.

Restreint de productions:

PostfixExpression :
    LeftHandSideExpression [no LineTerminator here] ++
    LeftHandSideExpression [no LineTerminator here] --

ContinueStatement :
    continue [no LineTerminator here] Identifieropt ;

BreakStatement :
    break [no LineTerminator here] Identifieropt ;

ReturnStatement :
    return [no LineTerminator here] Expressionopt ;

ThrowStatement :
    throw [no LineTerminator here] Expression ; 

L'exemple classique, avec l' ReturnStatement:

return 
  "something";
// is transformed to
return;
  "something";

52voto

Jörg W Mittag Points 153275

Directement à partir de l' ECMA-262, Cinquième Édition Spécification ECMAScript:

7.9.1 Règles Automatiques point-Virgule Insertion

Il y a trois règles de base du point-virgule insertion:

  1. Lorsque, comme le programme est analysé à partir de la gauche vers la droite, un jeton (appelé la délinquance jeton) est rencontré et qu'il n'est pas permis par la production de la grammaire, puis un point-virgule est automatiquement inséré avant le fautif jeton si l'une ou plusieurs des conditions suivantes est remplie:
    • La délinquance jeton est séparée de la précédente jeton par au moins un LineTerminator.
    • La délinquance token }.
  2. Lorsque, comme le programme est analysé à partir de la gauche vers la droite, à la fin du flux d'entrée de jetons est rencontré et de l'analyseur est impossible d'analyser les tokens d'entrée courant d'un seul compléter ECMAScript Program, puis un point-virgule est automatiquement inséré à la fin du flux d'entrée.
  3. Lorsque, comme le programme est analysé à partir de la gauche vers la droite, un jeton est rencontré et qu'il est autorisé par une partie de la production de la grammaire, mais la production est une production restreinte de la production et le jeton serait le premier jeton pour un terminal ou non-terminal en question immédiatement après l'annotation "[n LineTerminator ici]" dans la limité de la production (et donc comme un jeton est appelé un jeton restreint), et le jeton restreint est séparée de la précédente jeton par au moins un LineTerminator, puis un point-virgule est automatiquement inséré avant le jeton restreint.

Cependant, il existe une autre condition primordiale dans les règles précédentes: un point-virgule n'est jamais inséré automatiquement si le point-virgule serait alors être analysée comme une instruction vide ou si le point-virgule qui allait devenir l'un des deux points-virgules dans l'en-tête de pour la déclaration (voir 12.6.3).

19voto

George Jempty Points 3660

En ce qui concerne l'insertion de points-virgules et l'instruction var, prenez garde à oublier la virgule lors de l'utilisation de var mais en couvrant plusieurs lignes. Quelqu'un l'a trouvé dans mon code hier:

     var srcRecords = src.records
        srcIds = [];
 

La déclaration / affectation de srcIds était globale car la déclaration locale avec var sur la ligne précédente n'était plus appliquée car cette instruction était considérée comme terminée en raison de l'insertion automatique de points-virgules.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X