web-dev-qa-db-fra.com

En quoi la gestion des sauts de ligne par Python diffère-t-elle des points-virgules automatiques de JavaScript?

Javascript a une fonctionnalité appelée insertion automatique de point-virgule où, fondamentalement, si l'analyseur rencontre un jeton non valide, et le dernier jeton avant c'était un saut de ligne, l'analyseur insère un point-virgule où se trouve le saut de ligne. Cela vous permet d'écrire essentiellement tout votre code javascript sans point-virgule, mais vous devez être conscient de certains cas Edge, surtout si vous avez un mot-clé de retour, puis la valeur que vous souhaitez retourner sur une nouvelle ligne.

function test(){
    // This will return 'undefined', because return is a valid statement
    // and  "john" is a valid statement on its own.
    return 
          "john"
}

En raison de ces accrochages, il existe des dizaines d'articles avec des titres tels que "L'insertion automatique de points-virgules est mauvaise", "Toujours utiliser des points-virgules en Javascript", etc.

Mais en Python personne n'utilise jamais de point-virgule et il a exactement les mêmes gotchas.

def test():
    # This will return 'undefined', because return is a valid statement
    # and  "john" is a valid statement on its own.
    return 
    "john"

Fonctionne exactement de la même manière, et pourtant personne n'a peur du comportement de Pythons.

Je pense que les cas où le javascript se comporte mal sont assez peu nombreux pour que vous puissiez les éviter facilement. Retour + valeur sur une nouvelle ligne? Est-ce que les gens font vraiment ça beaucoup?

Des opinions? Utilisez-vous des points-virgules en javascript et pourquoi?

41
Einar Egilsson

La raison en est qu'en Python, les sauts de ligne sont un moyen non ambigu de séparer les lignes de code; c'est par conception, et la façon dont cela fonctionne a été soigneusement pensée. Par conséquent, python est parfaitement lisible et sans ambiguïté sans marqueurs de fin de déclaration spéciaux (à l'exception de la nouvelle ligne).

Javascript, d'autre part, a été conçu avec une syntaxe de type C à l'esprit, où les instructions se terminent toujours par un point-virgule. Pour rendre le langage plus tolérant aux erreurs, il essaie de deviner où les points-virgules supplémentaires doivent aller pour rendre le code correct. Comme il s'agissait d'une sorte de rétro-ajustement sur la syntaxe de type C, cela ne fonctionne pas toujours comme prévu (parfois, l'interpréteur de script se trompe) et peut créer un code assez contre-intuitif. \

Ou bien, argumenter en termes d '"explicite vaut mieux qu'implicite": en Python, une nouvelle ligne est déjà complètement explicite, tandis qu'en Javascript, elle est ambiguë, donc vous ajoutez le point-virgule pour le rendre explicite.

62
tdammers

Il y a une différence assez fondamentale avec la façon dont cela fonctionne en Python, je pense. Citant le post Einar Egilsson lié à: "un point-virgule n'est pas impliqué à la fin d'une ligne si le premier jeton de la ligne suivante peut être analysé dans le cadre de la même déclaration".

Dans Python un saut de ligne termine toujours l'instruction, sauf dans certains cas assez évidents comme dans une expression entre parenthèses. JavaScript, d'autre part, essaiera d'analyser autant de lignes qu'il peut avant mettre fin à la déclaration, ce qui pourrait conduire à des choses comme ceci:

// Define a function and name it area.
area = function(r) {
    return r * r * 3.14159
}

// Fooled you! We're actually invoking it.
(14)
28
Henrik

Je minimise souvent mes fichiers JS en mode production. Moyens, suppression des commentaires et des sauts de ligne.

Sans l'utilisation de points-virgules, cela briserait mon Javascript.

20
Deradon

Cela ne fonctionne pas comme vous le décrivez.

Javascript a une fonctionnalité appelée insertion automatique de point-virgule où, fondamentalement, si l'analyseur rencontre un jeton non valide, et le dernier jeton avant c'était un saut de ligne, l'analyseur insère un point-virgule où se trouve le saut de ligne.

C'est faux. Exemple:

return
  1 + 2;

1 est un jeton parfaitement valide, mais l'analyseur insérera toujours un point-virgule directement après return.

Comme vous le voyez, même vous ne pouvez pas dire exactement où un point-virgule se produira.

Le problème de l'insertion automatique est double:

  • D'une part, les gens peuvent laisser un point-virgule où l'insertion automatique ne peut pas déterminer que l'un doit être inséré.
  • En outre, un point-virgule peut être inséré là où il n'est pas prévu, comme ci-dessus.

Bien sûr, l'utilisation de points-virgules après chaque instruction n'aide que la première source d'erreurs.

En tout cas, comme vous pouvez le deviner maintenant, je pense que l'insertion automatique de points-virgules dans la syntaxe de type C est une mauvaise idée.

5
Svante

Je dirais une raison simple:

Javascript ressemble à "un peu Java-ish" ou "un peu C-ish". Bien sûr, c'est un langage dynamique donc il a l'air différent ... mais avouons-le - Il y a des accolades. Les langues avec accolades ont généralement des points-virgules. Les réflexes naturels se déclenchent et font avancer votre doigt vers la touche point-virgule avant vous frappez Enter.

Python, au contraire, même en un coup d'œil semble totalement différent. Par conséquent, peu ou pas d'analogie avec "les langages ennuyeux standard" se forme intuitivement et quand on entre en "mode python", le manque de les points-virgules sont aussi naturels.

4
Kos

Il existe un certain nombre de bonnes raisons pas d'utiliser l'insertion de points-virgules en JavaScript.

C'est principalement parce que l'insertion de points-virgules telle que définie dans la norme ECMAScript n'est pas intuitive dans certains cas. @Svante signale un cas pour return où l'utilisation de la nouvelle ligne causera des problèmes.

Ce qu'il ne mentionne pas, c'est que cela causera des problèmes si vous tilisez les points-virgules également, car l'insertion de points-virgules se produit, que vous le vouliez ou non.

Une autre très bonne raison de ne pas utiliser l'insertion de points-virgules est le contrôle de sortie. Dans de nombreux cas, JavaScript est exécuté à travers un minifieur avant d'être utilisé en production. Certains minificateurs peuvent gérer les cas d'insertion automatique de points-virgules, mais je ne vois aucune raison de compter sur son fonctionnement parfait

De plus, pour les systèmes de gestion de contenu, JavaScript en ligne peut être minifié automatiquement, et j'ai vu un certain nombre de cas où l'auto-minificateur supprime simplement les commentaires et supprime les espaces (y compris les nouvelles lignes) du début et de la fin de chaque ligne.

Pour les auteurs qui n'ont pas le choix des outils choisis, il est beaucoup plus facile de s'en tenir à un format qui fonctionne dans la grande majorité des cas.

2
zzzzBov

Ne pas utiliser de point-virgule est une recette d'échec lorsque vous réduisez vos fichiers JavaScript. C'est pourquoi j'en ai peur.

1
Eastern Monk

En Javascript, vous pouvez écrire un programme qui serait syntaxiquement correct en l'absence d'insertion automatique de point-virgule, et ASI transformera ce programme en différent programme syntaxiquement correct (par exemple, en transformant du code qui renvoie une valeur en code qui ne renvoie rien). Il n'y a pas de cas analogue en Python. Dans Python toute nouvelle ligne qui peut terminer une instruction va terminer une instruction, à moins qu'elle ne soit échappée avec une barre oblique inverse. Techniquement, je suppose que Les règles de Javascript sont également déterministes, mais je ne sais pas si vous pourriez résumer les règles de Javascript pour terminer les instructions en une seule phrase.

1
Ryan C. Thompson

Dans la plupart des cas, l'ASI de JavaScript gère les choses comme prévu. Un exemple d'ASI qui ne se comporte peut-être pas comme vous vous y attendez est le suivant:

var i = 0

(function() {
   // do something
})()

Cela sera interprété comme appelant la fonction 0 avec la fonction anonyme, puis en exécutant le résultat. Dans ce cas, vous souhaitiez probablement effectuer une affectation, puis exécuter immédiatement la fonction anonyme.

Pour quelqu'un qui n'est pas familier avec ASI, cela peut être très déroutant lorsque vous rencontrez des problèmes comme celui-ci, donc je recommande toujours aux développeurs de mon équipe d'utiliser des points-virgules.

(En passant: je n'utilise pas de points-virgules lorsque je travaille sur des projets personnels/secondaires parce que je sais que personne d'autre n'aurait besoin de maintenir le code.)

1
jay_soo

Comme vous, je pense que c'est un peu paranoïaque. Les règles pour l'insertion de points-virgules sont bien définies en JavaScript, tout comme elles le sont en Python et CoffeeScript. Personne ne lit Python ou CoffeeScript avec des points-virgules, alors pourquoi JavaScript traité différemment?

Je pense que c'est une réaction excessive à l'état misérable du code JavaScript typique d'il y a environ dix ans - JavaScript était considéré comme un langage faible, bogué, laid et pas bon. C'était gênant. Impossible d'écrire du bon code en JavaScript!

Ensuite, les gens sont venus et ont essayé de prouver que vous pouviez écrire du code beau et clair en JavaScript. La règle " utilise toujours des points-virgules" faisait partie de cette vague. Et pour être honnête, cela peut rendre certaines situations un peu plus claires.

Pourquoi JavaScript est-il toujours traité différemment?

Il y a de l'inertie. Et il ne faut pas oublier que les personnes qui apprécient le code explicitement structuré préfèrent souvent les langages de style C. Les personnes qui apprécient le code implicitement structuré passent souvent à des non Langages de style C (comme CoffeeScript).

1
Closure Cowboy

Je les utilise en Javascript uniquement pour des raisons de cohérence. Si la plupart des lignes ont

Python les a pour les cas Edge tels que plusieurs instructions sur une seule ligne, javascript les a et puisque vous les trouverez régulièrement utilisés, je me conforme à la norme où ils sont utilisés.

Je ne trouve pas d'utilisation pour plusieurs instructions sur la même ligne et je ne prévois donc pas d'utiliser des points-virgules.

0
Chris

Si vous utilisez quelque chose comme bundle-fu et gestionnaire d'actifs pour votre application web dans Rails, il se briserait horriblement s'il ne rencontrait pas de point-virgule à la fin du jeton en javascript. C'est donc une bonne pratique d'en mettre un.

0
subiet

Je ne me souviens pas quelle version exacte d'IE, mais il y a des cas où IE va littéralement se tromper si un point-virgule est manquant. IIRC c'est quand vous avez dans la portée globale quelque chose comme:

var myFunc = function() {
  ...
}

Si vous n'ajoutez pas le; après l'accolade fermante, le programme échouera réellement sur certaines versions d'IE. Cela, ainsi que les autres raisons (y compris la recommandation de Crockford de toujours les utiliser explicitement) m'ont amené à toujours les utiliser explicitement dans tous les cas.

0
apinstein