IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

Syntaxe des closures


Sujet :

JavaScript

  1. #1
    Membre du Club
    Homme Profil pro
    Intégrateur Web
    Inscrit en
    Septembre 2017
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : Suisse

    Informations professionnelles :
    Activité : Intégrateur Web
    Secteur : Bâtiment

    Informations forums :
    Inscription : Septembre 2017
    Messages : 6
    Par défaut Syntaxe des closures
    Bonjour,

    Toutes les documentations présentent les closures sous cette forme:
    (exemple trouvé dans https://www.w3schools.com/js/js_function_closures.asp)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    var add=(function(){
        var counter=0;
        return function() {return counter++;}
    })();
    Me demandant à quoi servait la première paire de parenthèses j'ai essayé de la supprimer et ça fonctionne pareil.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    var add=function(){
        var counter=0;
        return function() {return counter++;}
    }();
    Ces paranthèses sont-elles vraiment nécessaire?
    Merci d'avance pour vos réponses!

  2. #2
    Rédacteur/Modérateur

    Avatar de SpaceFrog
    Homme Profil pro
    Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Inscrit en
    Mars 2002
    Messages
    39 659
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 75
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2002
    Messages : 39 659
    Billets dans le blog
    1
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var add=(function(){
        var counter=0;
        return function() {return counter++;}
    })();
    console.log (add);
    var add1=function(){
        var counter=0;
        return function() {return counter++;}
    };
    console.log (add1);
    regarde en console...
    la première syntaxe est une fonction anonyme
    la seconde ne l'est pas
    Ma page Developpez - Mon Blog Developpez
    Président du CCMPTP (Comité Contre le Mot "Problème" dans les Titres de Posts)
    Deux règles du succès: 1) Ne communiquez jamais à quelqu'un tout votre savoir...
    Votre post est résolu ? Alors n'oubliez pas le Tag

    Venez sur le Chat de Développez !

  3. #3
    Membre du Club
    Homme Profil pro
    Intégrateur Web
    Inscrit en
    Septembre 2017
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : Suisse

    Informations professionnelles :
    Activité : Intégrateur Web
    Secteur : Bâtiment

    Informations forums :
    Inscription : Septembre 2017
    Messages : 6
    Par défaut
    Oui mais parce que tu as aussi enlevé la paire de parenthèse () à la fin de la déclaration de la fonction.
    Je me demande l'utilité de la paire de parenthèse qui "entoure toute la fonction", le résultat des ces deux variantes est cette fois identique.
    (peut-être pas pour tous les navigateurs?) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    var add=(function(){
        var counter=0;
        return function() {return counter++;}
    })();
    console.log (add);
    console.log (add());
    var add2=function(){
        var counter=0;
        return function() {return counter++;}
    }();
    console.log (add2);
    console.log (add2());
    Ca fonctionne je n'ai pas de problème mais j'aime bien comprendre les choses à fond ;-)
    Merci bcp!

  4. #4
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 207
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 207
    Par défaut
    Bonjour,
    Je me demande l'utilité de la paire de parenthèse qui "entoure toute la fonction"
    regarde du côté des IIFE.

  5. #5
    Membre Expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 910
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 910
    Par défaut
    Salut,

    Citation Envoyé par Philippe Bertschy Voir le message
    Je me demande l'utilité de la paire de parenthèse qui "entoure toute la fonction", le résultat des ces deux variantes est cette fois identique.
    Cette paire de parenthèses permet l'auto-exécution de la fonction, si tu l'écris sans l'affectation (ce qui ici n'a pas d’intérêt puisque que sans l’affectation on n'a pas de référence sur la fonction retournée) elle est quand même exécutée :

    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    (function () {
        var counter = 0;
        return function () {
            return counter++;
        }
    })();
    Par contre tu ne peux pas écrire ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    function () {
        var counter = 0;
        return function () {
            return counter++;
        }
    }();

  6. #6
    Expert confirmé
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 098
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 098
    Par défaut
    La différence est dûe au fait qu’il y a deux formes de fonction dans la syntaxe de JS : l’une est une instruction (statement), l’autre est une expression.

    En résumé, une instruction c’est un morceau de code séparé des autres instructions par des points-virgules, ou alors un bloc, ce qui inclut les structures comme if ou while.
    Code pseudocode : Sélectionner tout - Visualiser dans une fenêtre à part
    instruction ; instruction ; ...
    À l’opposé, une expression est une entité lexicale plus « fine ». Une instruction peut contenir une ou plusieurs expressions ; mais pas l’inverse. Les expressions sont ce qu’on utilise quand on fait des opérations +, -, etc., quand on passe des paramètres à une fonction, ou quand on affecte une valeur à une variable. Également, quand on utilise des parenthèses, ce qui est à l’intérieur est une expression.
    Code pseudocode : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // opération
    expression + expression
     
    // passage de paramètres
    uneFonction(expression, expression, ...)
     
    // affectation
    uneVariable = expression
     
    // parenthèses
    ( expression )

    Les deux formes des fonctions JS se ressemblent beaucoup, mais ne sont pas la même chose pour le lexer (analyseur lexical, le composant qui travaille en premier dans un moteur JS). La forme instruction est appelée fonction-déclaration et se présente comme ceci :
    Code pseudocode : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    function <nom> ( <listeArguments> ) {
      <corps>
    }

    Elle doit être précédée d’une autre instruction ou bien être en début de fichier. Lui donner un nom est obligatoire. Le truc important ici c’est qu’une fonction-déclaration est, comme son nom l’indique, une déclaration : le nom de la fonction reste dans la portée courante, afin qu’on puisse utiliser la fonction par la suite.

    À l’opposé, une fonction-expression n’a pas forcément de nom, et la fonction est « volatile », elle n’est pas rattachée à la portée courante.

    Code pseudocode : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ( function <nomOptionnel> ( <listeArguments> ) {
      <corps>
    } )
    Quand le lexer rencontre le mot-clé function là où une expression est attendue, il va automatiquement considérer qu’il s’agit d’une fonction-expression. On peut tirer parti de ce fait si on souhaite utiliser la fonction seulement une fois, ou si on veut éviter de polluer la portée.

    Ainsi, les parenthèses sont un des moyens de forcer le lexer à voir une fonction-expression. Mais comme tu t’en es rendu compte, l’affectation (signe égal) est un autre moyen. C’est simplement par souci de cohérence que des développeurs mettent systématiquement des parenthèses, même à des endroits où elles sont superflues.

    Une autre technique également répandue est le « point-virgule défensif » (defensive semicolon), qui consiste à faire précéder les parenthèses d’un point-virgule.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ;(function () {
      ...
    }());
    Cette technique est utile quand on travaille avec du code tiers et des outils de concaténation qui rassemblent plusieurs scripts en un seul fichier. Quand on ne sait pas ce qui précède dans le code, on peut tomber sur un cas malchanceux où notre parenthèse suit immédiatement le nom d’une autre fonction.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    fonctionDuCodeTiers(function () {
      ...
    }());
    Ce code est interprété comme si tu avais voulu passer ta fonction en paramètre à fonctionDuCodeTiers. Il en résulte des effets de bords indésirables. La technique du point-virgule défensif évite ça en « neutralisant » la fonction qui précède :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    fonctionDuCodeTiers;(function () {
      ...
    }());
    Quelques liens :
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  7. #7
    Membre du Club
    Homme Profil pro
    Intégrateur Web
    Inscrit en
    Septembre 2017
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : Suisse

    Informations professionnelles :
    Activité : Intégrateur Web
    Secteur : Bâtiment

    Informations forums :
    Inscription : Septembre 2017
    Messages : 6
    Par défaut
    Merci à tous pour vos réponses.
    Je n'aime pas faire les choses sans comprendre même si ça marche et vous m'avez permis de bien approfondir le sujet!

  8. #8
    Membre Expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 910
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 910
    Par défaut
    Merci Watilin pour les précisions...

    Bon ça va c'est ce que j'avais compris notamment en lisant ce fil : Explain the encapsulated anonymous function syntax mais ton explication est plus détaillée et plus claire et en français en plus...

  9. #9
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 207
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 207
    Par défaut
    Il y a, depuis peu, sur DVP : Tutoriel présentant les fonctions en JavaScript.

    Je n'ai d'ailleurs pas encore regardé

  10. #10
    Membre Expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 910
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 910
    Par défaut
    Merci.

    En effet ce tutoriel répond aussi à la question, on peut citer notamment ce passage :

    Donc la réponse complète à propos des parenthèses est la suivante :

    les parenthèses de l'opérateur de groupement sont requises quand une fonction ne se trouve pas à une position attendant une expression si vous souhaitez appeler immédiatement la fonction après sa création. Dans ce cas-là nous transformons juste manuellement une déclaration de fonction en expression de fonction.

    Dans le cas où l'analyseur sait déjà résoudre cette fonction comme une expression de fonction c'est-à-dire que la fonction est déjà à une position attendant une expression, les parenthèses ne sont pas obligatoires.

    Comme l'opérateur de groupement n'est qu'un moyen d'indiquer à l'analyseur que le code en cours doit être analysé comme une expression, il est possible d'utiliser tous les autres moyens pour transformer une instruction en une position nécessitant une expression pour créer une expression de fonction. Par exemple :

    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    // Ceci indique que nous manipulons une expression de fonction
    (function () {
        console.log("La gravité partagée");
    }());
     
    //, mais ceci aussi
    1, function () {
        console.log("Le monde d'en haut");
    }();
     
    // ainsi que ceci
    !function () {
         console.log("Le monde d'en bas");
    }();
     
    // et n'importe quelles autres
    // transformations manuelles
     
    /* ... */
    C'est juste que l'opérateur de groupement est la méthode la plus élégante et répandue.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [VB6] Syntaxe des requetes SQL
    Par Djaiffe dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 09/06/2006, 09h19
  2. [RegEx] preg_replace et syntaxe des expressions régulières
    Par MmoulinexX dans le forum Langage
    Réponses: 4
    Dernier message: 04/06/2006, 23h57
  3. Comprendre la syntaxe des triggers
    Par berceker united dans le forum MS SQL Server
    Réponses: 9
    Dernier message: 02/06/2006, 16h13
  4. [Tableaux] syntaxe des guillemets
    Par tioseb dans le forum Langage
    Réponses: 13
    Dernier message: 31/01/2006, 14h35
  5. vive la syntaxe des languages !
    Par D@rKness74 dans le forum Windows
    Réponses: 2
    Dernier message: 15/09/2004, 13h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo