Eh bien, je devrais d'abord demander si cela dépend du navigateur.
J'ai lu que si un jeton non valide est trouvé, mais que la section de code est valide jusqu'à ce jeton non valide, un point-virgule est inséré avant le jeton s'il est précédé d'un saut de ligne.
Cependant, l'exemple commun cité pour les bogues causés par l'insertion de points-virgules est:
return
_a+b;
..qui ne semble pas suivre cette règle, puisque _a serait un jeton valide.
D'un autre côté, la rupture des chaînes d'appels fonctionne comme prévu:
$('#myButton')
.click(function(){alert("Hello!")});
Quelqu'un at-il une description plus approfondie des règles?
Réponses:
Tout d'abord, vous devez savoir quelles instructions sont affectées par l'insertion automatique de points-virgules (également connue sous le nom d'ASI par souci de concision):
var
déclarationdo-while
déclarationcontinue
déclarationbreak
déclarationreturn
déclarationthrow
déclarationLes règles concrètes de l'ASI sont décrites dans la spécification §11.9.1 Règles d'insertion automatique des points-virgules
Trois cas sont décrits:
Lorsqu'un jeton (
LineTerminator
ou}
) est rencontré qui n'est pas autorisé par la grammaire, un point-virgule est inséré devant lui si:LineTerminator
.}
par exemple :
est transformé en
Le
NumericLiteral
1
répond à la première condition, le jeton suivant est un terminateur de ligne.Le
2
remplit la deuxième condition, le jeton suivant est}
.Lorsque la fin du flux de jetons d'entrée est rencontrée et que l'analyseur n'est pas en mesure d'analyser le flux de jetons d'entrée en tant que programme complet unique, un point-virgule est automatiquement inséré à la fin du flux d'entrée.
par exemple :
se transforme en:
Ce cas se produit lorsqu'un jeton est autorisé par une production de la grammaire, mais que la production est une production restreinte , un point-virgule est automatiquement inséré avant le jeton restreint.
Productions restreintes:
L'exemple classique, avec
ReturnStatement
:est transformé en
la source
++c
pour plus de clarté?Directement à partir de la spécification ECMAScript ECMA-262, cinquième édition :
la source
Je ne pouvais pas trop bien comprendre ces 3 règles dans les spécifications - j'espère avoir quelque chose qui est plus simple en anglais - mais voici ce que j'ai recueilli de JavaScript: The Definitive Guide, 6th Edition, David Flanagan, O'Reilly, 2011:
Citation:
Une autre citation: pour le code
et:
Je pense donc que pour simplifier, cela signifie:
En général, JavaScript traitera comme continuation du code aussi longtemps qu'il est logique - sauf 2 cas: (1) après quelques mots clés comme
return
,break
,continue
et (2) si elle voit++
ou--
sur une nouvelle ligne, il ajoutera le;
à la fin de la ligne précédente.La partie sur "le traiter comme une continuation de code aussi longtemps que cela a du sens" donne l'impression d'une correspondance gourmande d'expression régulière.
Cela dit, cela signifie
return
qu'avec un saut de ligne, l'interpréteur JavaScript insère un;
(cité à nouveau: si un saut de ligne apparaît après l'un de ces mots [tels que
return
] ... JavaScript interprétera toujours ce saut de ligne comme un point-virgule)et pour cette raison, l'exemple classique de
ne fonctionnera pas comme prévu, car l'interpréteur JavaScript le traitera comme:
Il ne doit pas y avoir de saut de ligne immédiatement après
return
:pour qu'il fonctionne correctement. Et vous pouvez insérer un
;
vous-même si vous deviez suivre la règle d'utilisation d'un;
après n'importe quelle déclaration:la source
En ce qui concerne l'insertion de points-virgules et l'instruction var, méfiez-vous de la virgule lorsque vous utilisez var mais sur plusieurs lignes. Quelqu'un a trouvé cela dans mon code hier:
Il a fonctionné, mais l'effet a été que la déclaration / affectation srcIds était globale car la déclaration locale avec var sur la ligne précédente ne s'appliquait plus car cette instruction était considérée comme terminée en raison de l'insertion automatique de points-virgules.
la source
var srcRecords = src.records srcIds = [];
sur une ligne et oubliez la virgule ou que vous écrivez "return a && b" et n'oubliez rien ... mais la coupure de ligne avant l'a insèrerait un point-virgule automatique après le retour, qui est défini par les règles ASI ...var
(let
,const
) sur chaque ligne l'emporte sur la fraction de seconde qu'il faut pour la taper.La description la plus contextuelle de l' insertion automatique de points-virgules de JavaScript que j'ai trouvée provient d'un livre sur Crafting Interpreters .
Il continue à le décrire comme vous coderiez l'odeur .
la source
Juste pour ajouter,
voir cela, en utilisant l'expression de fonction immédiatement invoquée (IIFE)
la source