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 function incompréhensible


Sujet :

JavaScript

  1. #1
    Membre actif
    Inscrit en
    Janvier 2011
    Messages
    35
    Détails du profil
    Informations forums :
    Inscription : Janvier 2011
    Messages : 35
    Par défaut syntaxe function incompréhensible
    bonjour, je suis en train d'apprendre javascript plus en profondeur et actuellement il n'y a rien qui n'echappe a google

    mais voila il y a une syntaxe que je n'arrive pas a définir

    exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    var cookie = (function () {
     
    // code
     
    })();
    quand est ce que le bloc de code sera exécuté et a quoi sert en général cette syntaxe ?

    évidement la recherche de function javascript sur google retourne rien donc si vous avez des documents la dessus ce serrait super


    ok je vient de tester et donc la fonction s'execute seule ! dans ce cas, quelle est la difference entre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    var f = (function(){
     
    // code
     
    })();
    et

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    function f(){
     
    // code
     
    }
     
    f();

  2. #2
    Modérateur

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

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 198
    Par défaut
    Bonjour,
    - dans le cas de la syntaxe var f = (function(){...} tu pourras prototyper f
    - dans le cas de la syntaxe function f(){...} tu ne fais qu'un simple nommage de fonction.
    cas #1 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    var test = function(){
      // le code
    };
    test.prototype.show = function(){
      alert('a.prototype.show Yes!');
    };
    var a = new( test);
    a.show();
    dans le cas #2 tu ne peux pas...

    edit 1 : j'admets cela reste léger comme explication...
    edit 2 : biffage de l'ânerie !

  3. #3
    Invité
    Invité(e)
    Par défaut
    bonjour,

    lorsque tu déclares
    il y a une pré compilation ou le moteur va rendre la fonction accessible dans le scope ou elle a été définie. genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    function g(){} //g est accessible partout
    function f(){function g(){}}//f est accessible partout, mais g est accessible que dans f
    De fait, tu peux écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    g('toto');
    function g(str) {alert('toto');}
    bien que g est définie 'après', elle est accessible lors de l'exécution du code au sein du scope ou elle a été définie (ici l'objet globale window).

    Lorsque tu écris
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    var f=(function(){})();
    tu définis f au moment du mot clé var.

    Donc si tu écris
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    f('toto');
    var f=(function(){return function(str){alert(str);}})()
    ca va merder.

    la syntaxe de la dernière sert à créer une fonction anonyme.
    Par exemple tu ne peux pas écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    function test(){}();//pour appeler test directement.
    si tu as des variables avec lesquelles tu ne veux pas polluer ton scope tu crees une fonction anonyme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    (function(){
     var toutCeQueJeVEuxOnSenFout='lol';
    })();
    et tu fais ton stuff dedans

    Enfin attention, on peut prototyper une fonction qqsoit le cas.

  4. #4
    Membre Expert
    Avatar de Eric2a
    Homme Profil pro
    Technicien
    Inscrit en
    Septembre 2005
    Messages
    1 225
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Corse (Corse)

    Informations professionnelles :
    Activité : Technicien

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 225
    Par défaut
    Salut,

    Un petit code où nous pouvons voir qu'il est bien entendu possible de passer des arguments à la fonction.
    Code : 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
    20
    21
    22
    23
    24
    25
    26
    27
    // Déclaration de l'objet global "myObject" et éxecution avec argument
    var myObject=(function(lang){
    	// Déclaration de la variable privée "language"
    	var language;
     
    	// Déclaration de la fonction privée "setLng" et éxecution avec argument
    	(function setLng(lang){
    		language=(lang=='fr')?'fr':'en';
    	})(lang); // Une pierre, deux coups
     
    	// Retourne un objet
    	return{
    		// Déclaration des méthodes publiques
    		setLanguage:function(lang){
    			setLng(lang);
    		},
    		showWelcome:function(){
    			alert((language=='fr')?'Salut et bienvenue':'Hello and welcome');
    		}
    	}
    })('fr'); // Langue "fr" par défaut
     
    // Tests...
    myObject.showWelcome(); // Salut...
     
    myObject.setLanguage('en');
    myObject.showWelcome(); // Hello...

  5. #5
    Modérateur

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

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 198
    Par défaut
    Enfin attention, on peut prototyper une fonction qqsoit le cas.
    oùla! je vais me faire descendre à écrire des âneries...
    ...on peut effectivement prototyper une fonction nommée.

    Revenons juste à la différence
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    var fct = function(){
      // code 
    };
    fct est une variable qui fait référence à la fonction.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    function fct(){
      // code 
    };
    fct est le nom de la fonction.

    et le cas dont nous parle manserk
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    var fct = (function(){
     // code
    })();
    fct est le résultat retourné par la fonction anonyme après exécution

  6. #6
    Invité
    Invité(e)
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    // Déclaration de la fonction privée "setLng" et éxecution avec argument
    (function setLng(lang){
    	language=(lang=='fr')?'fr':'en';
    })(lang); // Une pierre, deux coups
    setLng n'est pas disponible dans le scope de myObject.
    Autrement dit ,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    setLanguage:function(lang){
    	setLng(lang);
    },
    provoque une erreur sur l'appel de setLng.

  7. #7
    Modérateur

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

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 198
    Par défaut
    NoSmoking 1 : galerien69 1
    Citation Envoyé par galerien69
    setLng n'est pas disponible dans le scope de myObject.
    la fonction est bel et bien disponible...à preuve le code fourni par Eric2a tourne...

    l'écriture
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    (function setLng(lang){
    	language=(lang=='fr')?'fr':'en';
    })(lang); // Une pierre, deux coups
    indique qu'une fois la fonction définie celle ci est exécutée

    nota : je pense qu'il va falloir acheter/lire JavaScript : Gardez le meilleur !

  8. #8
    Invité
    Invité(e)
    Par défaut
    lol le 1-1
    attention, il va peut-etre se transformer en décisif!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (function test(){console.log('lol')})(); test();
    tourne la première pas la seconde...

  9. #9
    Expert confirmé
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 094
    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 094
    Par défaut
    Chez moi j'ai une erreur :
    Erreur : setLng is not defined
    Alors pour dissiper le mystère je vais tout de suite donner le nom de cette chose : c'est une fermeture lexicale. On utilise aussi le terme anglais, closure.

    Pour creuser un peu dans la structure du langage, faut regarder les parenthèses :
    Code JS : Sélectionner tout - Visualiser dans une fenêtre à part
    (function() { … })();

    Les parenthèses vertes encadrent la déclaration de notre fonction, ce qui forme un ensemble parenthèses + fonction, que l'interpréteur va considérer comme une expression. Ceci a pour effet intéressant de provoquer l'interprétation immédiate de la fonction.

    En rouge, nous avons les parenthèses habituelles qui servent à appeler une fonction. Ainsi, la fonction qui vient d'être interprétée est à présent exécutée. Ensuite, comme elle faisait partie d'une expression, elle n'est pas gardée en mémoire, peu importe qu'elle ait été nommée ou non.

    Comme l'a dit galerien69, les closures permettent de protéger ses variables. En effet, les variables locales déclarées dans la fonction sont inaccessibles depuis l'extérieur. Du moins… En théorie ! Car un phénomène étrange se produit parfois :
    Code JS : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    var f = (function() {
    	var x = 0;
    	function addX( y ) {
    		x += y;
    	}
    	return addX;
    })();
    Là, nous avons une fonction locale, addX, qui a réussi à s'échapper du contexte local de la fonction anonyme. Elle est à présent référencée par la variable f. Voyons ce qui se passe :
    Code JS : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    f(3); // 3
    f(4); // 7
    f(2) // 9
    La variable locale x est toujours vivante ! En fait, quand une fonction sort d'une closure, l'interpréteur garde dans un coin une référence sur l'ensemble des variables locales, pour pouvoir les réutiliser. Et ces variables restent en mémoire tant que la fonction n'est pas détruite.

    Moi je trouve que ça ressemble à un objet avec des variables privées, mais chacun voit ce qu'il veut
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  10. #10
    Membre Expert
    Avatar de Eric2a
    Homme Profil pro
    Technicien
    Inscrit en
    Septembre 2005
    Messages
    1 225
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Corse (Corse)

    Informations professionnelles :
    Activité : Technicien

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 225
    Par défaut
    Citation Envoyé par Eric2a
    "Une pierre, deux coups !"
    Tu parles

    Je donne la pierre pour me faire lapider et donne le baton pour reçevoir les coups

    J'aurais codé ça...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    (function UglyFunc(data){
    	document.write( eval( data ) );
    })(dataFromExternalWebSite);
    C'était pareil


    <justification type="tentative" status="honteux" cause="IE notamment">
    En fait, quand j'ai vu que le (désormais pseudo-) code ci-dessous fonctionnait, je me suis dit "Tiens ?! Ca marche !"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    (function setLng(lang){
    	language=(lang=='fr')?'fr':'en';
    })(lang); // Une pierre, deux coups
    J'aurais du spécifier que je n'ai testé que sur IE8.
    </justification>

    Opera (et je présume tous les autres aussi) réagit comme il faut en renvoyant une erreur.

  11. #11
    Membre actif
    Inscrit en
    Janvier 2011
    Messages
    35
    Détails du profil
    Informations forums :
    Inscription : Janvier 2011
    Messages : 35
    Par défaut
    Merci c'est plus clair pour moi maintenant

    même si a la premiere lecture ça l'était pas

  12. #12
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Billets dans le blog
    20
    Par défaut
    @watilin
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    var f = (function() {
    	var x = 0;
    	function addX( y ) {
    		x += y;
    	}
    	return addX;
    })();
    Ici, la variable globale f va recevoir le résultat renvoyé par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    (function() {
    	var x = 0;
    	function addX( y ) {
    		x += y;
    	}
    	return addX;
    })();
    à savoir la fonction addX elle-même. Or la fonction addX contient dans son scope la variable x dont elle a besoin pour s'exécuter, donc le garbage collector doit préserver x, mais qui ne sera accessible que par f
    Pas de question technique par MP !
    Tout le monde peut participer à developpez.com, vous avez une idée, contactez-moi !
    Mes formations video2brain : La formation complète sur JavaScriptJavaScript et le DOM par la pratiquePHP 5 et MySQL : les fondamentaux
    Mon livre sur jQuery
    Module Firefox / Chrome d'intégration de JSFiddle et CodePen sur le forum

  13. #13
    Expert confirmé
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 094
    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 094
    Par défaut
    Certes !
    Mais le garbage-collector ne peut pas savoir quelles variables sont susceptibles de se trouver dans le scope de la fonction, notamment à cause de l'existence d'eval, ou encore si la closure contient des objets qui se référencent les uns les autres. Du coup il doit garder toutes les variables.
    Code JS : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    var f = (function() {
    	var x = 3;
    	var y = 'mca';
    	var reponse = 42;
    	function surprise( nomVar ) {
    		return eval(nomVar);
    	}
    	return surprise;
    })();
     
    alert(f('reponse'));
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  14. #14
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2011
    Messages
    442
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2011
    Messages : 442
    Par défaut
    Citation Envoyé par Watilin Voir le message
    Chez moi j'ai une erreur :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    var f = (function() {
    	var x = 0;
    	function addX( y ) {
    		x += y;
    	}
    	return addX;
    })();
    t'es sûr que ça marcherait pas mieux avec :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    var f = (function() {
    	var x = 0;
    	function addX( y ) {
    		return x += y;
    	}
    	return addX;
    })();

  15. #15
    Modérateur

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

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 198
    Par défaut
    Citation Envoyé par Eric2a
    J'aurais du spécifier que je n'ai testé que sur IE8.
    j'ai également testé avec le navigateur que j'avais sous la main, à savoir IE7, et aucun doute il n'y a qu'avec IE que cela fonctionne.

    Il semblerait que nous soyons en présence d'une fuite de mémoire et que la référence soit maintenue.

  16. #16
    Expert confirmé
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 094
    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 094
    Par défaut
    Attention, tant qu'il reste une référence, ce n'est pas une fuite !
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  17. #17
    Invité
    Invité(e)
    Par défaut
    De toute façon, IE est une référence

  18. #18
    Membre Expert
    Avatar de Eric2a
    Homme Profil pro
    Technicien
    Inscrit en
    Septembre 2005
    Messages
    1 225
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Corse (Corse)

    Informations professionnelles :
    Activité : Technicien

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 225
    Par défaut
    Ayant WinXP, je ne peux pas tester IE9. Je voudrais savoir par curiosité si ce dernier renvoie aussi function comme ses prédécesseurs au lieu de undefined.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    (function test(){
    	return;
    })();
    alert('typeof test = ' + typeof test);
    Merci

  19. #19
    Modérateur

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

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 198
    Par défaut
    cette fuite de mémoire reste bien inférieure à la mienne

    Citation Envoyé par Watilin Voir le message
    Attention, tant qu'il reste une référence, ce n'est pas une fuite !
    c'est une façon de voir les choses, mais attendu qu'une fonction expression, "ne survit pas", voir ce qu'en dit la "spécification"...
    ...IE dans ce cas ne libère pas la mémoire, néanmoins il est capable de se resservir de l'objet crée, et c'est en quoi effectivement on peut ne pas parler de réelle fuite de mémoire.

    edit to Eric2A, navré pas de IE9 pour moi non plus...

  20. #20
    Membre Expert
    Avatar de RomainVALERI
    Homme Profil pro
    POOête
    Inscrit en
    Avril 2008
    Messages
    2 652
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : POOête

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 652
    Par défaut
    Merci à tous pour cette intéressante discussion, mais j'avoue que j'ai eu un léger choc en lisant ce détail dans le post initial...
    Citation Envoyé par manserk Voir le message
    évidement la recherche de function javascript sur google retourne rien
    Citation Envoyé par recherche Google
    Recherche : function javascript
    Citation Envoyé par résultats Google
    Environ 145 000 000 résultats (0,10 secondes)
    Mais bon ça n'a plus d'importance...

Discussions similaires

  1. Babel 5.4.0 : test de la nouvelle syntaxe function bind
    Par vermine dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 21/05/2015, 16h55
  2. syntaxe java incompréhensible
    Par africanwinners dans le forum Langage
    Réponses: 4
    Dernier message: 24/02/2013, 18h26
  3. Syntax error incompréhensible dans script shell!
    Par Sakesannin dans le forum Shell et commandes GNU
    Réponses: 3
    Dernier message: 22/01/2010, 18h41
  4. Syntaxe Function Loop
    Par chakcc dans le forum C
    Réponses: 10
    Dernier message: 21/11/2006, 14h25
  5. [syntaxe] " = function()"
    Par Loceka dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 15/05/2006, 15h13

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