Partage
  • Partager sur Facebook
  • Partager sur Twitter

a propos de closure

    26 mai 2011 à 9:54:30

    Bonjour,

    Je suis en train de travailler sur la notion de closure; j'aimerais reprendre le code suivant

    function MaFonction(nombre) {
    	function Ajouter(valeur) {
    		// La variable "nombre" est accessible dans cette fonction, car "nombre"
    		// a été définie en dehors de la fonction Ajouter
    		return nombre + valeur;
    	}
    
    	// Comme on l'a vu, Ajouter est une variable, j'ai donc le droit de la rendre en
    	// tant que résultat de la fonction
    	return Ajouter;
    }
    
    var a = MaFonction(10);
    // La variable "a" contient désormais la fonction "Ajouter". "a" est désormais une
    // fonction dans laquelle la variable "nombre" existe encore.
    
    alert( a(2) ); // Affiche "12";
    



    Pouvez-vous me dire quelle est la valeur de l'argument valeur de la fonction Ajouter.
    D'après mes connaissances sur le passage de paramètes dans des fonctions, j'en conçois que lorsqu'on appelle la fonction MaFonction(10); , l'argument 10 est affecté à la variable argument "nombre"; mais qu'en est il de l'argument "valeur"; quelle valeur prend il lors de cet appel?

    J'avoue que cela est assez confus encore pour moi.
    Faut il appeler deux fois la fonction MaFonction pour pourvoir faire un ajout de 2 à 10?

    Merci beaucoup de vos réponses.

    Par ailleurs, dans l'exemple 9 du cours
    var a = ["elem1", "elem2", "elem3", "elem4", "elem5"];
    
    for(var i = 0; i < 3; i++) {
    	window.setTimeout(
    		/* Argument 1 : Fonction à lancer après le délai */
    		function() { alert(a[i]) },
    		/* Argument 2 : Délai en millisecondes avant de lancer la fonction */
    		1000
    	);
    }
    

    Vous expliquez que la variable i prend la valeur 3 après le délai de 1000 ms(=1 s).
    Je ne comprends pas qu'il puisse ne être ainsi du fait que la boucle for limite la valeur de i à 2( i va de 0 à 2).
    Pouvez-vous m'expliquer à quel moment i a pu passer à la valeur 3.

    Merci beaucoup de vos explications sur ces points un peu flous encore.
    Pour finir, dans votre cours, il est expliqué qu'en javascript on considère qu'une fonction est une variable "spéciale", comme le montrent les exemples suivants; tous ces jeux d'affectation ne sont pas réalisables avec d'autres langages de haut niveau tels que java.
    Pouvez-vous me confirmer que javascript est bien 'spécial' en son genre sur ces points-ci.


    // Une fonction peut être définie ainsi :
    function UneFonction() {
    	alert("Je suis une fonction");
    }
    
    UneFonction(); // affiche "Je suis une fonction"
    
    // mais on peut aussi la définir ainsi :
    // (On affecte en fait une fonction anonyme à une variable)
    var UneAutreFonction = function() {
    	alert("Je suis une autre fonction");
    };
    
    UneAutreFonction(); // affiche "Je suis une autre fonction"
    
    // Une fonction étant une variable, on peut lui réaffecter une valeur :
    UneFonction = "Je ne suis plus une fonction :'(";
    
    alert(UneFonction); // affiche "Je ne suis plus une fonction :'("
    
    // On peut passer une fonction comme argument à une autre fonction (comme n'importe quelle autre variable)
    function UtiliserFonction(fct) {
    	fct(); // ici, on exécute la fonction passée en paramètre
    }
    
    UtiliserFonction(UneAutreFonction); // affiche "Je suis une autre fonction"
    


    Merci beaucoup à vous de vos réponses et de votre aide.

    Cordialement.

    curieuse_prog
    • Partager sur Facebook
    • Partager sur Twitter
      26 mai 2011 à 10:40:57

      Pour ton closure, ta variable a contient la fonction Ajouter donc quand tu lui passes 2, valeur est égal à 2 et nombre est toujours égal à 10, tu as donc comme résultat 12. En fait, Ajouter garde une référence vers la variable nombre.

      Alors pour ton exemple 9 avec la boucle for.

      En fin de boucle, i est augmenté. Il fait donc le traitement pour i = 2 et une fois la boucle exécutée, i passe à 3. La condition de la boucle est évaluée et est fausse et on passe à la suite.

      JavaScript est un langage à prototype. C'est un peu déroutant et ça peut effectivement sembler spécial... mais il y a d'autres langages à prototype, c'est juste pas les plus connus.
      • Partager sur Facebook
      • Partager sur Twitter
        26 mai 2011 à 12:04:30

        Pour compléter ce qu'à dit Valérian ou plutôt pour formuler d'une manière différente.

        Tu peux essayer de comprendre ce qu'il se passe en regardant le fonctionnement de l'espace mémoire (ou plus précisément de la portée des variables).

        Dans ton premier exemple:
        Dans ton espace de travail global (qu'on va appelé EdT1):
        On crée une fonction nommée MaFonction
        On crée une variable une variable a dans lequel on lui colle le retour de la fonction MaFonction.

        A ce moment, on appelle la fonction. Donc on crée un nouvel espace de travail (qu'on va appelé EdT2).
        Dans EdT2, on crée une variable nombre qui a pour valeur 10 (ce qui correspond au paramètre donné lors de l'appel)
        on crée une fonction appelée Ajouter.
        On quitte la fonction MaFonction en retournant une référence à la fonction Ajouter qui est dans EdT2.

        donc la variable a (qui est dans EdT1) contient une référence à Ajouter qui est dans EdT2

        Lorsqu'on exécute le alert, on fait appelle à a. Donc indirectement on exécute la fonction Ajouter qui est dans EdT2.
        On crée alors un nouvel espace de travail pour cette fonction (qu'on va appelé EdT3), dans lequel on crée une variable valeur qui a pour valeur 2 (la valeur du paramètre)
        Ensuite on retourne la somme de nombre (comme aucune variable nombre n'existe dans EdT3, on regarde dans l'espace de travail parent, c'est à dire EdT2. Dans celui-ci il y a une variable nombre qui vaut 10) et valeur (qui vaut 2). Le retour vaut donc 12


        Dans ton 2e exemple (celui avec la boucle for):
        Si on regarde les fonctions anonymes qui sont créées dans le setTimeout.

        au moment les fonctions sont appelées (donc 1s après la boucle).
        On cherche une variable a qui n'existe que dans l'espace de travail global.
        on cherche une variable i qui n'existe que dans l'espace de travail global or la valeur de i est maintenant 3 (car la boucle est finie) donc cela revient à afficher a[3];


        Citation : curieuse_prog

        Pouvez-vous me confirmer que javascript est bien 'spécial' en son genre sur ces points-ci.


        Ben c'est la manière de fonctionner du javascript. Donc dire que c'est "spécial" est exagéré car comme l'a dit Valérian d'autres langages fonctionnent de la même manière.
        • Partager sur Facebook
        • Partager sur Twitter

        a propos de closure

        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
        × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
        • Editeur
        • Markdown