Javascript

Masquer apartés

Fonctions

Sans rentrer dans des détails, dans d'autres langages, et parfois même en javascript, on pourra rencontrer le terme de méthode "à la place" du terme de fonction.

En plus de l'opérateur + rencontré, le type String définit d'autres opérations qu'il est possible d'appliquer sur ses valeurs. Il s'agit de fonctions. Une fonction est une entité qui accepte des données en entrée, réalise un traitement puis fournit un résultat.

A quoi vous fait penser cette définition (informelle) sur les fonctions ?
La notion de fonction ne différe pas fondamentalement celle en mathématique, ainsi la fonction sin admet-elle un seul paramètre de type nombre et fournit un résultat de type nombre. Simplement nous utiliserons des fonctions qui auront plusieurs paramètres (on utilise le terme de variable en mathématique) et ces paramètres ne seront pas nécessairement des nombres.

Les données (en entrée) d'une fonction sont appelées paramètres. Il peut y avoir plusieurs paramètres à une fonction et ce nombre est fixé à la définition de la fonction. Il ne peut cependant y avoir qu'un résultat. Lorsque l'on utilise une fonction, on parle d'appel de fonction, il faut fournir des valeurs pour les paramètres. Le traitement réalisé par la fonction, et en conséquence son résultat, dépend des valeurs des paramètres.

Par habitude, on dit qu'une fonction renvoie ou retourne un résultat, on parlera donc de valeur retournée ou renvoyée par une fonction.

La notion de "fonction qui ne renvoie pas de résultat" peut sembler en contradiction avec la notion mathématique et le terme de procédure est parfois utilisée pour désigner les fonctions sans résultat.

Dans certain cas particuliers, une fonction n'a pas besoin de retourner un résultat, seul le traitement réalisé compte. C'est par exemple le cas de la fonction writeln de document que nous avons déjà rencontrée.

Les types des paramètres ne sont pas quelconques. A nouveau ils sont fixés à la définition de la fonction. Lorsque l'on appelle une fonction, il faut fournir des valeurs dont le type correspond à celui attendu. Mais il faut bien évidemment également connaiître la nature de la valeur attendue, savoir qu'il faut un nombre ne suffit pas, il faut savoir si ce nombre correspond à une température, à une somme d'argent, à la durée en secondes d'un morceau de musique, etc.

En plus des informations en permettant la bon utilisation, le commentaire décrivant la spécification d'une fonction peut indiquer le nom de son créateur, la date de création ou un numéro de version. Il constitue d'une certaine manière la carte d'identité de la fonction.

Pour pouvoir appeler une fonction il faut donc connaître les informations concernant les paramètres : leur nombre, leurs types, et à quoi ils correspondent. Pour pouvoir l'utiliser il faut également savoir à quoi correspond son résultat et quel traitement est réalisé. Toutes ces informations sont décrites dans la spécification de la fonction (qui correspond à ce que nous avons vu pour l'opérateur d'addition en renommant simplement opérande en paramètre). La donnée de la spécification doit suffire à l'utilisation d'une fonction.

Lorsqu'une fonction est définie pour un type de donnée particulier, l'utilisation de cette fonction, son appel, sur une donnée de ce type s'écrit en utilisant la notation pointée. Nous l'avons déjà rencontrée avec document.writeln qui est en fait un appel de la fonction writeln sur une donnée de type Document, ce type de données correspondant à une page chargée dans le navigateur. Evidemment le résultat dépend de la donnée sur laquelle s'utilise ou s'applique la fonction, on utilisera aussi par la suite l'expression "donnée concernée".

Nous verrons qu'il existe également des fonctions dites globales qui ne sont pas définies par un type particulier. Dans ce cas leur appel se fait simplement en utilisant le nom de la fonction, sans utiliser la notation pointée.

Exemple

Il existe une fonction getHours sur le type Date. De même que l'opérateur + existe pour les nombres et pour les chaines de caractères, on peut imaginer qu'une fonction de nom getHours puisse être définie pour un autre type de donnée. Par exemple une donnée Spectacle qui permetrait de gérer des spectacles, la fonction getHours fournirait alors peut-être l'heure de début du spectacle. Il est donc indispensable de préciser dans la spécification pour quel type la fonction est spécifiée.

Voici une spécification de getHours du type Date :

type concerné : Date
nom : getHours
Paramètres : 0
Résultat :
  type : un nombre
  description : l'heure de la date concernée

Cette spécification nous suffit pour savoir comment utiliser cette fonction sur une donnée de type Date :

var maintenant = new Date();                                  // date a pour la valeur la date courante
var nbHeures = maintenant.getHours();                         // heures a pour valeur le nombre d'heures de Date
document.writeln("le nombre d'heures est " + nbHeures);       // on affiche ce nombre d'heures (on note l'utilisation de la concaténation)
document.writeln("ou encore :" + maintenant.getHours());      // il n'est pas obligatoire de définir une variable pour utiliser le résultat
document.writeln("ou encore :" + new Date().getHours());      // ni même pour la date

Il existe de nombreuses autres méthodes similaires qui s'appliquent sur et permettent la manipulation des données de type Date : getFullYear, getMinutes, getMonth, getSeconds et getMilliseconds.

Ecrivez une page qui affiche de manière détaillée à raison de une par ligne les informations de la date courante (au moment du chargement de la page). Utilisez une feuille de style pour présenter l'information.

Conversion de types

Cette conversion se fait à l'aide de fonctions. Ainsi il existe la fonction parseInt qui prend en paramètre une chaîne de caractères et dont le résultat est l'entier correspondant au contenu de cette chaîne de caractères, lorsque cela est possible. De manière similaire il existe une fonction parseFloat qui permet la conversion d'une chaîne en un nombre "à virgule flottante" lorsque cela est possible.

Quelques précisions sont nécessaires quant au fonctionnement des ces fonctions :

  • seul le premier nombre dans la chaîne est retourné, les autres caractères (y compris correspondant à des nombres) sont ignorés,
  • si le premier caractère ne peut être converti en un nombre, le résultat sera NaN,
  • les espaces en tête sont ignorés,
  • avec parseInt il est possible de préciser un second paramètre qui sera la base (8, 10, 16) à utiliser pour analyser la chaîne.

Exemples :

parseFloat("1.24");                ==>   1.24
parseInt("42");                    ==>   42
parseInt("42 est la réponse");     ==>   42
parseInt("    42 est la réponse"); ==>   42
parseInt("1.24");                  ==>   1
parseInt("42estlaréponse");        ==>   42
parseInt("42 43 44");              ==>   42
parseInt("réponse = 42");          ==>   NaN
parseInt("10",16);                 ==>   16
parseInt("AA",16)                  ==>   170
Vous avez sûrement remarqué que la fonction parseInt s'appelle "directement" sans utilisation de la notation pointée. Il s'agit d'un exemple de fonctions globales que nous avons déjà évoquées précédemment. Ces fonctions sont définies indépendamment d'un type de donnée particulier.
Expliquez les 2 derniers résultats.
Ecrivez la spécification de parseInt.

La fonction parseInt peut donc être appliquée au résultat d'un appel à la fonction prompt pour produire un nombre, lorsque cela a un sens :

var texteSaisi = prompt("Donnez une valeur entière");
var unEntier = parseInt(texteSaisi);

Mais dans la mesure ou la fonction parseInt prend pour paramètre une chaîne de caractères et que la fonction prompt a pour résultat une chaîne de caractères, on peut également "enchainer" les appels de fonction sans passer par une variable intermédiaire :

var unEntier = parseInt(prompt("Donnez une valeur entière"));

On obtient ainsi le moyen d'obtenir une valeur entière saisie par l'utilisateur.

Il s'agit exactement de la notion mathématique de composition, lorsque l'on écrit ln(sin(x)) il s'agit bien de calculer la valeur de sin(x) avant d'appliquer à cette valeur ln. On retouve également cette composition en Sciences Physiques avec cos(ωt+φ) qui compose la fonction qui à t associe ωt+φ avec la fonction cos.

On réalise dans ce cas une composition d'appels de fonction.

Créez une page HTML qui demande à l'utilisateur de saisir deux entiers et dont le contenu produit sera :
 Le résultat de la somme de xx et yy est res.
xx et yy sont les nombres saisis et res leur somme.
Faites plusieurs tests. Pensez à tester des saisies non valides (non numériques) et à étudier ce qu'il se passe.
L'opérateur + lorsqu'il est utilisée avec une opérande de type String et une autre numérique considère aussi une conversion implicite de l'opérande numérique en chaîne. 4+"you" est donc évaluée en la chaîne "4you". On aurait dû écrire (4).toString()+"you" (les parenthèses sont nécessaires avec des constantes numériques).
On trouve assez régulièrement l'exploitation par des programmeurs de cette conversion implicite lorsqu'ils ont besoin d'une conversion (explicite) d'un nombre en chaîne. Il écrivent alors par exemple ""+4 qui revient à (4).toString().

Certaines conversions de type sont réalisées "automatiquement" par le langage : le langage applique implicitement une conversion, c'est-à-dire sans que le programmeur ait à "demander" cette manipulation. C'est ce qui se passe par exemple avec la fonction writeln que nous avons déjà beaucoup utilisée. Le paramètre de cette fonction doit être de type String or nous avons pu écrire :

var x = 12;
document.writeln(x);

Cela est possible car Javascript réalise automatiquement l'appel d'un traitement qui convertit la donnée numérique 12 en la chaîne "12" avant d'exécuter le traitement du writeln. Si le langage ne réalisait pas à notre place cette conversion il faudrait écrire : document.writeln(x.toString()); Ce qui alourdit le code pour une fonction assez souvent utilisée. Les concepteurs du langage ont ici voulu faciliter le travail des programmeurs.

On souhaite créer une page qui permet la conversion d'une température exprimée en Fahrenheit en Celsius puis l'inverse.
  1. Recherchez sur internet les formules de conversion entre ces unités de mesure.
  2. Ecrivez le code qui demande la saisie d'une température en Fahrenheit et affiche la température Celsius équivalente.
  3. Ecrivez le code qui demande la saisie d'une température en Celsius et affiche la température Fahrenheit équivalente.
  4. Testez la page créée.
  1. Réalisez un page HTML qui après avoir demandé la saisie de 2 valeurs correspondant à une latitude et une longitude sous forme de nombres à virgule affiche la "google map" centrée sur ces coordonnées.
    Rappel : le code pour afficher une image google map ressemble à ceci :
    <img src="http://maps.googleapis.com/maps/api/staticmap?center=50.609731,3.137511&zoom=17&size=400x400&sensor=false" /> .
  2. Avez-vous transformé les données lues en données de type float ? Si oui, fallait-il absolument le faire ? Si non, pourquoi n'était-ce pas indispensable ?
  3. Modifiez la page afin que l'utilisateur ait à fournir en plus la valeur du facteur de zoom et la taille d'affichage (on pourra conserver une image carrée) avant l'affichage.
  4. Testez !
 

Articles

Vidéos