Syntaxe d'appel de fonction immédiate

110

Il existe une option JSLint , une des bonnes parties en fait, qui "[requiert] des parenthèses autour des invocations immédiates", ce qui signifie que la construction

(function () {

  // ...

})();

devrait plutôt être écrit comme

(function () {

  // ...

}());

Ma question est la suivante - quelqu'un peut-il expliquer pourquoi cette deuxième forme pourrait être considérée comme meilleure? Est-ce plus résilient? Moins sujet aux erreurs? Quel avantage a-t-il sur la première forme?


Depuis que j'ai posé cette question, j'en suis venu à comprendre l'importance d'avoir une distinction visuelle claire entre les valeurs de fonction et les valeurs de fonctions. Prenons le cas où le résultat de l'appel immédiat est le côté droit d'une expression d'affectation:

var someVar = (function () {

  // ...

}());

Bien que les parenthèses les plus extérieures soient syntaxiquement inutiles, la parenthèse ouvrante donne une indication initiale que la valeur attribuée n'est pas la fonction elle-même mais plutôt le résultat de la fonction appelée.

Ceci est similaire au conseil de Crockford concernant la capitalisation des fonctions du constructeur - il est destiné à servir de repère visuel à quiconque regarde le code source.

Bobby Eickhoff
la source
Merci de l'avoir signalé. Je n'ai jamais trouvé un moyen de me débarrasser du message d'avertissement de JSLint "Soyez prudent lorsque vous créez des fonctions dans une boucle." J'étais prudent et j'ai mis la fonction dans une fermeture mais JSLint s'est toujours plaint. Maintenant, je sais qu'il a supposé que j'ai utilisé le deuxième modèle.
viam0Zah
Je l'ai fait «mal» tout ce temps. Et quand je dis «tout ce temps», j'écris du JavaScript depuis 1995.
Dave Land

Réponses:

73

Extrait du guide des conventions de style de Douglass Crockford : (recherchez "invoked immédiatement")

Lorsqu'une fonction doit être appelée immédiatement, l'expression d'appel entière doit être entourée de parenthèses afin qu'il soit clair que la valeur produite est le résultat de la fonction et non la fonction elle-même.

Donc, fondamentalement, il pense que cela rend plus claire la distinction entre les valeurs de fonction et les valeurs de fonctions. C'est donc une question de style, pas vraiment une différence de fond dans le code lui-même.

référence mise à jour, l'ancien PPT n'existe plus

cgp
la source
1
Je suis content d'avoir lu ceci. Je viens de finir de lire Javascript: The Good Parts, et ce que je n'arrêtais pas de penser, c'est que l'attribution du résultat de l'appel d'une fonction est une très mauvaise syntaxe, car il faut regarder les première et dernière lignes pour comprendre ce qui se passe. Il n'utilise pas les parens enveloppants dans le livre, mais je vois exactement pourquoi il les recommande.
Skilldrick
2
@altCognito, pouvez-vous fournir un nouveau lien pour le PPT?
th1rdey3
1
J'ai cherché sur le Web, mais je ne trouve toujours pas de copie de ce PPT
Forethinker
1
Je n'ai pas pu trouver le PPT original, mais j'ai pu trouver le même point trouvé dans son guide de convention javascript.
cgp
archive.org l'avez-vous?
John Greene
2

Les fonctions anonymes immédiatement appelées sont encapsulées dans des parenthèses car:

  1. Ce sont des expressions de fonction et laisser les parenthèses de côté entraînerait son interprétation comme une déclaration de fonction qui est une erreur de syntaxe.

  2. Les expressions de fonction ne peuvent pas commencer par le mot fonction.

  3. Lors de l'affectation de l'expression de fonction à une variable, la fonction elle-même n'est pas renvoyée, la valeur de retour de la fonction est renvoyée, par conséquent, les parents évaluent ce qu'ils contiennent et produisent une valeur.lorsque la fonction est exécutée, et les parenthèses de fin ..}()provoquent l'exécution immédiate de la fonction.

Dathan
la source
Dathan, vous répondez à une autre question. Vous avez raison de dire que les parenthèses englobantes sont parfois nécessaires d'un point de vue syntaxique pour que l'analyseur puisse distinguer les expressions de fonction des déclarations de fonction. Mais ma question porte sur le placement des parenthèses d'invocation. Votre troisième point est inexact; les parenthèses englobantes ne sont pas nécessaires dans ce cas.
Bobby Eickhoff
Je répondais à votre premier exemple où la fonction anonyme immédiatement appelée n'a pas été affectée à une variable et donc les parenthèses sont syntaxiquement nécessaires pour les 2 premières raisons. La troisième raison était juste de rétablir ce que vous aviez même dit: "la parenthèse ouvrante donne une indication initiale que la valeur assignée n'est pas la fonction elle-même mais plutôt le résultat de la fonction invoquée." Mais je suppose que ce n'était pas clair.
Dathan
-3

Ou utiliser:

void function () {
...
} ()
Agamemnus
la source