• Facile

Ce cours est visible gratuitement en ligne.

Vous pouvez être accompagné et mentoré par un professeur particulier par visioconférence sur ce cours.

J'ai tout compris !

Mis à jour le 14/08/2017

Retour sur les fonctions

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Revenons sur un sujet abordé quelques chapitres plus tôt : les fonctions.
C'est une notion récurrente en JS, et il y a encore pas mal de choses à en dire !
Cependant, vous savez déjà des choses à leur sujet : créer des fonctions qui prennent des arguments et qui renvoient des valeurs... bref, tout ce qu'il faut savoir pour les utiliser ;) .

Mais ce chapitre va apporter un regard nouveau : on va découvrir qu'une fonction, ce n'est en fait... qu'une variable ! o_O
On va également apprendre à créer des fonctions auxquelles on peut donner n'importe quel nombre d'arguments, selon notre envie, mais surtout selon notre besoin...

Rassurez-vous : rien de bien compliqué, vous avez déjà acquis toutes les notions nécessaires dans les chapitres précédents ;) .

Fonctions et variables

Enregistrer une fonction dans... une variable ?!

Nous avons, dans les chapitres précédents, étudié séparément les variables et les fonctions.
Mais en fait, une fonction, ce n'est pas si différent que ça d'une variable...

Rappel

Histoire de vous rafraîchir un peu la mémoire, je vous rappelle qu'une fonction se déclare dans l'en-tête de la page, de cette manière :

function toto(arg1, arg2)
{
        // code
        return valeur;
}

Quelques explications succinctes pour se remettre dans le bain :

  • Le mot-clé function indique... qu'on déclare une fonction ;)

  • toto est le nom de notre fonction

  • arg1 et arg2 sont les arguments de cette fonction, séparés par une virgule, et mis entre des parenthèses qui sont obligatoires (même s'il n'y a aucun argument).

  • On place le code de la fonction dans un bloc d'instructions, délimité par des accolades.

  • On renvoie éventuellement une valeur (c'est la valeur que "prendra" la fonction quand on l'appellera).

Créer une fonction dans une variable

Eh bien figurez-vous qu'il existe une autre manière de créer une fonction, en utilisant une variable.
Voyez plutôt :

var toto = function(arg1, arg2)
{
        // code
}

Cette fois-ci :

  • On a déclaré notre variable, à l'aide du mot-clé var (comme nous avons vu dans le chapitre à ce sujet).

  • On a donné à notre variable le nom de toto.

  • On lui a affecté(on lui a donné pour valeur) une fonction, prenant deux paramètres nommés arg1 et arg2, et exécutant le code entre les accolades.

Mais alors, si ce sont les mêmes fonctions, quel est l'intérêt d'utiliser cette nouvelle méthode plutôt que l'ancienne ?

C'est en fait un autre point de vue, assez différent : en déclarant une fonction de cette manière, on voit clairement qu'on enregistre notre fonction dans une variable.

On peut donc très facilement :

  • créer une fonction locale ou globale

  • re-déclarer une fonction (autrement dit, modifier son code), simplement en modifiant la variable

  • créer des tableaux de fonctions

  • etc.

Exemple : un tableau de fonctions

Pour vous montrer, créons un tableau de fonctions.
Pour cela, on commence par déclarer notre tableau, comme on l'a appris auparavant, puis on associe à chaque élément (chaque case) une fonction, comme nous venons de le voir :

var operation = new Array();
   operation["add"] = function(x,y){ return x+y; };
   operation["soustr"] = function(x,y){ return x-y; };
   operation["mult"] = function(x,y){ return x*y; };
   operation["div"] = function(x,y){ return x/y; };
   operation["moy"] = function(x,y){ return (x+y)/2; };

On fait un essai : on demande deux nombres à l'utilisateur, ainsi que le nom de la fonction à appliquer (add, soustr, mult, div ou moy).

var a = parseFloat( prompt("Premier nombre ?") );
var b = parseFloat( prompt("Deuxieme nombre ?") );
var fct = prompt("Fonction a appliquer ?");

var resultat = operation[fct](a,b);
alert("Resultat : " + resultat);

C'est quand même plus joli que d'effectuer cinq if à la suite, pas vrai ? :)

Rappel : portée des variables

Puisqu'on parle de variable, un petit rappel concernant la portée de celles-ci ne sera pas inutile...

En JavaScript, on distingue les variables globales (accessibles n'importe où dans votre code) des variables locales.
Les variables locales déclarées dans une fonction ne seront accessibles (et "visibles") qu'à l'intérieur de cette fonction. On peut donc sans problème utiliser le même nom pour des variables locales de deux fonctions différentes.

Comment ça marche ?

  • On déclare une variable locale à l'aide de var, dans le bloc d'instructions (qui est généralement "matérialisé" par des accolades) dans lequel elle doit être accessible.

  • Il y a deux façons de créer une variable globale : soit en la déclarant en dehors de tout bloc d'instructions (tout au début du code JS), soit on l'utilise sans la déclarer, comme si elle l'avait déjà été (on parle alors de déclaration implicite).

Un exemple :

var a;  // on declare une variable globale
function test(argument)
{
        var resultat = 5*argument + 2;
        a = argument;   // modification de la variable globale
        b = resultat;   // declaration implicite d'une variable globale
        return resultat;
}
  • Lorsque la fonction n'a pas été appelée, il y a une seule variable globale : a.

  • Quand on appelle la fonction, celle-ci modifie cette variable globale, et on en déclare (implicitement) une autre : b.

  • Une fois la fonction exécutée, on peut toujours accéder aux variables a et b, car elles sont globales.

  • Cependant, on ne peut accéder à la variable resultat uniquement à l'intérieur de la fonction, car c'est une variable locale.

Voilà, ce n'était finalement pas compliqué ;) .

Les arguments facultatifs : nombre fixé d'arguments

Plutôt que de vous faire un long discours théorique, voyons ensemble le fonctionnement.

Comment ça se passe lorsqu'on appelle une fonction ?

Prenons une fonction comme celle-ci :

function f(x,y)
{
        // code de la fonction
}

Elle a pour nom f, et prend deux paramètres, x et y.

Que se passe-t-il si on l'appelle en ne précisant qu'un seul argument, comme ci-dessous ?

f(5);

Essayons de comprendre ce qui va se passer lors de cet appel :

  • deux variables locales, x et y, vont être créées (ce sont les arguments)

  • la variable x va être initialisée avec la valeur 5 (c'est la valeur qu'on a donnée lors de l'appel pour le premier argument)

  • mais y ne sera pas initialisée, car on n'a pas précisé le second argument

Autrement dit, il va se passer quelque chose comme ceci :

var x, y;
x = 5;
// code de la fonction

Une variable non initialisée !

Quels sont les symptômes ?

On se retrouve donc face à une variable déclarée, mais... qui n'a pas de valeur !
Poursuivons donc nos essais : que va-t-il se passer avec un tel code ? :pirate:

var y;
alert(y);

On voit alors s'afficher : undefined.

Comment ça se soigne ?

On peut effectuer un test comme celui-ci pour vérifier si la variable y est définie :

if(y == undefined)

Et on peut aussi créer une fonction qui renvoie true ("vrai", cf. le chapitre sur les conditions) si la variable est définie, false sinon.

function isDefined(variable)
{
   return (variable != undefined);
}

Exemple

Tout ça pour dire qu'on peut créer des fonctions pour lesquelles certains arguments sont facultatifs.

Un exemple : une fonction dist(a,b) qui calcule la distance entre a et b (autrement dit, la valeur absolue de b-a).
Mais si on appelle dist(a), on veut que la fonction calcule la valeur absolue de a (la distance entre a et 0).

Comment faire ?
Pour le calcul de la distance, pas de problème, on teste si a est plus grand que b, et on calcule a-b ou b-a selon le cas.
En revanche, la nouveauté se trouve dans le second point : si on ne donne qu'un seul paramètre, il va falloir initialiser b à 0.

function dist(a,b)
{
   // on initialise b a 0 si besoin
   if(b == undefined)
      b = 0;
   // on continue ensuite normalement
   if(a > b)
      return a-b;
   else
      return b-a;
}

Au début de la fonction, il faut donc vérifier si les arguments facultatifs ont été précisés : si ce n'est pas le cas, il va falloir leur donner une valeur par défaut.

Les arguments facultatifs : nombre illimité d'arguments

C'est bien gentil tout ça, mais ça ne permet pas de réaliser la fonction d'addition dont on a parlé quelques chapitres plus tôt, qui additionnait tous les arguments qu'elle avait !

En effet, on avait parlé d'une fonction qui devait pouvoir s'utiliser comme ceci :

addition(12, 5);   // nous donnerait 17
addition(21, 4, 15, 11, 6);   // nous donnerait 57
// etc. avec autant de nombres qu'on veut

Où sont stockés tous ces arguments ?

Ce qui serait pratique, c'est que les arguments soient numérotés... un peu comme... un tableau !
Justement, il est possible de récupérer un tableau qui contient tous les arguments de la fonction. Du coup, le problème semble tout de suite plus simple :) .

Un tableau contenant tous les arguments

Partons de la fonction d'addition qu'on veut réaliser. On peut déjà commencer par la créer comme ceci :

function addition()
{
   // corps de la fonction
};

Maintenant, il nous faut récupérer le tableau contenant les arguments.
Ce tableau est addition.arguments : ce sont les argumentsdela fonction addition, stockés sous forme de tableau.

Petite parenthèse : le point rouge . ne vous rappelle-t-il pas monTableau.length, qui est la longueurdemonTableau ?

Le tour est joué !

Eh bien on a gagné !
Non ? Je vous sens sceptiques...

Commençons par créer une variable contenant ce tableau, qu'on va appeler nb (les arguments sont les nombres à additionner) :

var nb = addition.arguments;

Et maintenant, il ne reste plus qu'à tout additionner (qui dit tableau, dit boucle...), ce qui nous donne cette fonction :

function addition()
{
   var nb = addition.arguments;
   var somme = 0;
   for(var i=0; i<nb.length; i++)
      somme += nb[i];
   return somme;
};

Il ne nous reste plus qu'à tester (le moment le plus stressant en programmation :D ) :

alert( addition(12, 5) );
alert( addition(21, 4, 15, 11, 6) );

Qui nous affiche bel et bien 17, puis 57 :) .

Notez qu'on peut très bien appeler addition(), sans aucun paramètre : le résultat est 0.

Un autre exemple

Pour que ce soit bien clair pour vous, étudions un nouvel exemple : une fonction, prenant encore une fois autant de paramètres (des nombres) qu'on veut, et qui renvoie le plus grand de ces nombres.

Cette fois-ci, à la différence de l'addition, on ne sait pas trop quoi renvoyer s'il n'y a aucun paramètre...
On va donc créer une fonction comme ceci :

function maxi(m) { };

On va ensuite parcourir le tableau, et enregistrer la plus grande valeur "lue" dans une variable (on peut utiliser la variable m) : cette variable contiendra donc le plus grand nombre parmi ceux qu'on a déjà parcourus.

function maxi(m)
{
   var nb = maxi.arguments;   // on a donc m = nb[0]
   for(var i=1; i<nb.length; i++)
      if(nb[i] > m)   // si l'argument est plus grand que le maximum...
         m = nb[i];   // ... alors c'est le maximum
   return m;
}

Et, encore une fois, on peut tester :

var n = maxi(7, 3);
alert(n);

var p = maxi(2, 8, 4, 1, 9, 4);
alert(p);

Remarquez au passage que cette dernière fonction peut s'avérer utile :) .

Et voilà, cette fois-ci, nous y sommes !
Enfin prêts !
Après tant de labeur, des chapitres pas toujours drôles... vous connaissez maintenant tout ce qu'il faut savoir (la syntaxe du JS) pour vous attaquer à... la POO !

En effet, le JavaScript, c'est avant tout de la Programmation Orientée Objet. Mais pour l'instant, nous n'avons pas vu l'ombre d'un objet. Enfin si, quelques allusions par-ci par-là, mais presque rien.

Par contre, dès les prochains chapitres, on va apprendre à interagir avec le visiteur en utilisant la page web, et vous verrez qu'on en a, des possibilités !

Et voilà, cette première partie touche à sa fin... nous allons maintenant pouvoir nous attaquer au "vrai" JavaScript :) .

Exemple de certificat de réussite
Exemple de certificat de réussite