Partage
  • Partager sur Facebook
  • Partager sur Twitter

Déclaration de fonction

Sujet résolu
    16 septembre 2021 à 12:35:12

    Bonjour à tous,

    Je suis en train de suivre le cours "Apprenez à programmer en Javascript", actuellement rendu au début de la troisième partie du cours qui se nomme "Travailler sur les fonctions".

    Il y a un exercice où je dois récupérer des valeurs dans plusieurs tableaux pour ensuite en faire une moyenne. Le problème c'est que dans l'énoncé, on me demande de déclarer une fonction qui permet de faire une moyenne, que je pourrais ensuite me servir après avoir récupéré les valeurs des tableaux avec une boucle For... of.

    Jusque-là tout vas bien, ça m'as l'air plutôt simple.

    Mais quand je regarde la solution du prof à l'exercice, surprise, je ne trouve aucune fonction, ni aucune déclaration de fonction.

    Donc je suis actuellement bloqué sur un cours où la solution de l'exercice n'est pas la même que son énoncé... Même si la solution final du prof fonctionne, je ne la comprends pas...

    Si quelqu'un pourrait m'expliquer où se trouve la "déclaration de fonction" dans la solution du prof, ça serait top ! Car mis à part la déclaration de constante au début du code, je ne trouve pas...

    La solution :

    // Modify the code here
    // ==========================================
    
    const calculateAverageRating = (ratings) => {
      
      if(ratings.length === 0) {
        return 0;
      }
      
      let sum = 0;
      for (let rating of ratings) {
        sum += rating;
      }
      
      return sum / ratings.length;
    
    }
    
    // ============================================
    
    const tauRatings = [5, 4, 5, 5, 1, 2];
    const colinRatings = [5, 5, 5, 4, 5];
    
    const tauAverage = calculateAverageRating(tauRatings);
    const colinAverage = calculateAverageRating(colinRatings);
    
    if (tauAverage && colinAverage) {
      document.querySelector('#tau-score').innerText = tauAverage.toFixed(1) + ' stars';
      document.querySelector('#colin-score').innerText = colinAverage.toFixed(1) + ' stars';
      document.querySelector('#clara-score').innerText = `${calculateAverageRating([]) === 0 ? 'No ratings' : calculateAverageRating([]) + ' stars'}`
    }

    Merci infiniment d'avance à celui ou ceux qui passeront par là ! :)

    -
    Edité par Sally98 16 septembre 2021 à 12:49:15

    • Partager sur Facebook
    • Partager sur Twitter
      16 septembre 2021 à 13:04:53

      La déclaration de la fonction est faite à la ligne 4.
      Je sais, c'est un peu perturbant, surtout que pour avoir parcouru récemment ce cours, je ne me souviens pas avoir vu qu'il parlait des "arrow functions". C'est tout simplement une manière raccourcie de déclarer une fonction :

      // fonction déclarée de manière classique
      const fonction1 = function(argument) {
         //corps de la fonction
      }
      
      // fonction déclarée comme "arrow function"
      const fonction2 = (argument) => {
         //corps de la fonction
      }

      La différence est subtile, au lieu de mettre le mot-clé function avant les parenthèses contenant ( ou non ) le ou les arguments, on met => après ces parenthèses.

      Les lignes 24 et 25 montrent que l'appel à la fonction se fait de la même manière.
      Là où c'est un peu vache, c'est à la ligne 30, ça fait appel à des notions que moi-même je maîtrise encore assez mal ( l'opérateur ternaire, dont on ne parle pas dans ce cours, par exemple ) et concrètement je ne comprend pas ce que fait cette instruction, mis à part prouver que ta fonction retourne bien la valeur 0 quand on lui passe un array vide en argument.

      • Partager sur Facebook
      • Partager sur Twitter
        16 septembre 2021 à 13:16:50

        Tout d'abord, je te remercie grandement pour ta réponse rapide et ton explication très concrète !

        Effectivement, il ne parle pas une seule fois de cette façon de déclarer une fonction... Je viens d'aller voir les cours suivant et il utilise toujours cette façon s'en jamais l'expliquer donc ça prête à confusion pour un débutant comme moi...

        J'ai une dernière petite question, histoire d'éclaircir au maximum le sujet des fonctions :

        Est-ce qu'une fonction déclaré en "arrow functions" doit toujours être dans une constante ?

        Tu viens de me débloquer sur le sujet, je vais pouvoir continuer le cours donc encore merci ! :)

        • Partager sur Facebook
        • Partager sur Twitter
          16 septembre 2021 à 14:29:51

          Non, il n'y a rien de particulier concernant les arrow functions, c'est juste une histoire de notation. C'est un poil plus rapide à écrire, par contre j'ai fait une drôle de tête quand j'en ai vu pour la première fois ^^
          J'ai appris le javascript il y a plus de dix ans, ça n'existait pas, alors bon, ça m'a surpris.

          Mais donc pour reprendre la réponse à ta question, rien ne t'empêche de déclarer une variable "contenu", dont tu pourras afficher la valeur dans un élément HTML, et la valeur de cette variable peut changer. Au départ c'est un contenu par défaut ( var contenu = "bonjour" ), puis plus tard dans le script, cette valeur sera le résultat d'une fonction ( arrow ou pas ), puis plus tard changer encore...

          Donc tu peux tout à fait affecter le résultat d'une fonction à une variable. Le mot-clé const, c'est pour les constantes, c'est à dire les variables dont la valeur ne doit pas changer.
          Là je m'aperçois que la formulation de mon code est maladroite, au lieu de "fonction1" et "fonction2" j'aurais du écrire "résultat1" et "résultat2", car précisément ce qui est fait ici c'est déclarer une variable ( ou dans mon exemple une constante ) et dans la foulée lui affecter une valeur, cette valeur étant le résultat d'une fonction.
          Et, en l'occurrence, je m'aperçois que le corrigé du cours openclassrooms utilise une fonction anonyme !
          Moi j'ai plutôt tendance à faire de manière classique :

          function ajouter(arg1, arg2)
          {
             return arg1 + arg2;
          } //dans un premier temps je déclare la fonction
          
          var resultat = ajouter(5, 2); //resultat vaut 7.

          J'utilise les fonctions anonyme dans les callbacks ( fonctions qui seront exécutées par certaines fonctions, comme addEventListener() ) :

          var element = document.getElementById('monElement'); //ici je crée une référence à un élement HTML présent dans ma page web, élément qui porte un attribut 'id' égal à "monElement"
          
          element.addEventListener('click', () => {alert("vous avez cliqué sur mon élément!"};
          //la fonction addEventListener prend deux arguments, le premier est le nom de l'évènement, le deuxième est une fonction, appelée "callback", qui sera exécutée quand l'évènement se produit. Elle n'a pas besoin d'avoir un nom.

          Ici, j'utilise une fonction anonyme, avec la syntaxe "arrow function".
          La démarche de Will Alexander est plus difficile à expliquer à un débutant.
          Il créé une constante ayant pour nom calculateAverageRating, dont la valeur est une référence à une fonction anonyme.
          Je ne pense pas que ça change grand-chose au fait d'écrire "function calculateAverageRating(ratings) {}", si ce n'est, peut-être, une manière de "protéger" le nom calculateAverageRating, qui ne pourra pas être utilisé ailleurs dans le script ( ce qui pourrait écraser la fonction ).
          Bon, à mon sens un "bon" cours expliquerais bien les différentes manières de faire une même chose, parce que des fois on prend ses petites habitudes, et on est parfois surpris quand on regarde le travail de quelqu'un d'autre.


          • Partager sur Facebook
          • Partager sur Twitter
            16 septembre 2021 à 15:22:36

            D'accord ! C'est dingue, tu expliques tellement bien, avec des exemples concrets, que limite j'aurais préféré que ça soit toi l'auteur du cours ! :D

            Je te remercie grandement pour ton temps, ça m'as tellement aidé à mieux comprendre les exemples ainsi que les exercices du cours. Tu m'as fais gagner un temps précieux ! ;)

            • Partager sur Facebook
            • Partager sur Twitter
              16 septembre 2021 à 15:35:15

              Moi ?! Auteur de cours ? :lol:

              Je suis loin d'avoir le niveau requis. Disons que j'ai pas mal potassé sur un ou deux projets et que j'ai assimilé quelques bases. Mais c'est vrai que des fois, on a la pédagogie mais pas la science, ou alors on a la science, mais pas la pédagogie ;)

              Bonne continuation à toi, heureux d'avoir pu t'aider.

              • Partager sur Facebook
              • Partager sur Twitter
                16 septembre 2021 à 16:15:18

                Salut,

                Juste une différence très importante entre la déclaration classique d'une fonction et la version flécher : Une fonction flécher ne retient pas le contexte dans lequel elle est utilisée.

                Quand je parle de contexte, je veux parler du petit this qui peut être utiliser dans certaines situations.

                Par exemple :

                document.addEventListener('scroll', function() {
                    console.log(this); // Renvoi 'document' parce que le contexte d'utilisation de cette fonction est préservé et qu'il s'agit de 'document'.
                });
                
                document.addEventListener('scroll', () => {
                    console.log(this); // Renvoi 'window' parce que le contexte de cette fonction fléchée n'est pas préservé et que par défaut, 'this' vaut 'window' sur un navigateur.
                });
                

                C'est loin d'être anodin et il faut toujours garder en tête que la fonction fléchée présente cet inconvénient...

                Quant à l'opérateur ternaire, c'est rien de plus qu'un operateur permettant sur une seule ligne de vérifier une condition et de renvoyer un résultat en fonction de cette condition :

                `${calculateAverageRating([]) === 0 ? 'No ratings' : calculateAverageRating([]) + ' stars'}`
                // Si calculateAverageRating([]) vaut 0 ('?' vaut 'if'), alors on renvoi la string 'No ratings', sinon (':' vaut 'else'), on renvoi la string composée du résultat de calculateAverageRating([]) suivit par ' stars'...

                Pas si compliquer que ça tant qu'on ne s'amuse pas à les enchainer :

                calculateAverageRating([]) === 0 ? 'No ratings' :
                calculateAverageRating([]) === 1 ? '1 star' : 
                calculateAverageRating([]) > 1 ? calculateAverageRating([]) + ' stars';

                Encore que...

                • Partager sur Facebook
                • Partager sur Twitter
                  16 septembre 2021 à 16:24:46

                  LucasWerquin a écrit:

                   Le mot-clé const, c'est pour les constantes, c'est à dire les variables dont la valeur ne doit pas changer.

                  Bonjour, j'interviens juste pour une petit correction, moi aussi je pensais au début qu'une constante ne devais pas changer, cela n'est pas tout à fait vrai notamment pour les objets et tableaux.

                  Attention, la déclaration constcrée une référence en lecture seule vers une valeur. Cela ne signifie pas que la valeur référencée ne peut pas être modifiée ! Ainsi, si le contenu de la constante est un objet, l'objet lui-même pourra toujours être modifié.

                  Source : https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Statements/const

                  La déclaration d'une constante empêche une nouvelle assignation, en utilisant les méthodes  adéquates on peut modifier une clés d'un objets et les valeurs d'un tableau. 

                  On pourrait très bien n'utiliser que des constantes et utiliser let si une réaffectation serait nécessaire.

                  Sinon bravo Lucas pour ton explication claire.

                  • Partager sur Facebook
                  • Partager sur Twitter
                    16 septembre 2021 à 16:39:13

                    BrainError a écrit:

                    Salut,

                    Juste une différence très importante entre la déclaration classique d'une fonction et la version flécher : Une fonction flécher ne retient pas le contexte dans lequel elle est utilisée.

                    Quand je parle de contexte, je veux parler du petit this qui peut être utiliser dans certaines situations.

                    Par exemple :

                    document.addEventListener('scroll', function() {
                        console.log(this); // Renvoi 'document' parce que le contexte d'utilisation de cette fonction est préservé et qu'il s'agit de 'document'.
                    });
                    
                    document.addEventListener('scroll', () => {
                        console.log(this); // Renvoi 'window' parce que le contexte de cette fonction fléchée n'est pas préservé et que par défaut, 'this' vaut 'window' sur un navigateur.
                    });
                    

                    C'est loin d'être anodin et il faut toujours garder en tête que la fonction fléchée présente cet inconvénient...

                    Super ! Merci à toi pour cette précision, il faudrait vraiment que je mette la main sur des docs plus pointues que ce que j'ai consulté ces derniers temps, ce genre de "petits détails" n'y sont pas expliqués m'ont causés quelques crises de nerfs ^^

                    AbcAbc6 a écrit:

                    Bonjour, j'interviens juste pour une petit correction, moi aussi je pensais au début qu'une constante ne devais pas changer, cela n'est pas tout à fait vrai notamment pour les objets et tableaux.

                    Attention, la déclaration constcrée une référence en lecture seule vers une valeur. Cela ne signifie pas que la valeur référencée ne peut pas être modifiée ! Ainsi, si le contenu de la constante est un objet, l'objet lui-même pourra toujours être modifié.

                    Source : https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Statements/const

                    La déclaration d'une constante empêche une nouvelle assignation, en utilisant les méthodes  adéquates on peut modifier une clés d'un objets et les valeurs d'un tableau. 

                    On pourrait très bien n'utiliser que des constantes et utiliser let si une réaffectation serait nécessaire. 

                    Et bien merci à toi pour cette correction, il faudra que je revoie ma copie ^^

                    Si j'ai bien compris, les constantes qui pointent vers un type primitif ( booléen, nombre ou string ) ne pourrontpas être modifiées ( ex const pi=3.14 ), mais en ce qui concerne les références vers les objets, c'est la référence en elle-même qui est constante, pas l'objet ?

                    Allez, et si vous nous faisiez une suite au cours sur le javascript ? ;)







                    -
                    Edité par LucasWerquin 16 septembre 2021 à 16:52:18

                    • Partager sur Facebook
                    • Partager sur Twitter
                      17 septembre 2021 à 17:46:38

                      Tiens, en farfouillant sur le net, je suis tombé sur un blog que j'ai adoré, et dans ce blog un article qui explique aussi une différence de taille entre fonction déclarée de manière classique et arrow function :

                      Javascript : ce que j'avais pas compris - Je suis un dev

                      Cet article explique assez bien aussi pourquoi on considère à tort que javascript est simple, alors que quand on commence à faire des trucs un peu plus poussés, on rencontre des gros soucis si on ne creuse pas un peu plus loin dans le fonctionnement du truc.

                      • Partager sur Facebook
                      • Partager sur Twitter

                      Déclaration de fonction

                      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                      • Editeur
                      • Markdown