Accueil

Traduction

Tutoriel sur Javascript

Recherche dans ce tuto

L'auteur : Patrick Darcheville

Vous pouvez me contacter via Facebook pour questions & suggestions : Page Facebook relative à mon site

JavaScript : les fonctions


Tous les langages proposent des fonctions natives ou prédéfinies c'est à dire prêtes à l'emploi.
Dans tous les langages le développeur peut créer ses propres fonctions ou fonctions personnelles.
Il ne faut pas confondre fonctions génériques et méthodes.

Les fonctions prédéfinies de JavaScript

Nous avons déjà utilisé dans nos scripts : parseInt(), parseFloat(), isNaN().
Ce sont des fonctions natives JavaScript.
Les fonctions natives et génériques sont peu nombreuses en JS par contre le nombre de méthodes est impressionnant.

Fonctions et méthodes

Ne confondez pas fonction et méthode.
Une fonction n'est pas liée à un objet ou une classe.
Une fonction est appelée directement en utilisant son nom.
La syntaxe est : nomFonction(paramètre1, paramètre2, ...)

Une méthode est une fonction particulière associée à un objet ou une classe.
Une méthode est appelée en utilisant la syntaxe : objet.methode(paramètres)

Par exemple, vous pouvez appliquer à un objet de type String les méthodes trim(), toUpperCase(), toLowerCase() etc. (et seulement à une chaine).
JavaScript propose aussi des méthodes pour les dates, les 'arrays', les 'maps', les 'sets', etc.
Tout un chapitre est consacré aux objets natifs de JS et leurs méthodes : les objets natifs de JS
Dans le chapitre 9 vous apprendrez à créez vos propres objets avec leurs propriétés et méthodes : Créer ses propres objets

Tests

Tapez les commandes suivantes dans la console !

>unechaine ="    aAbBcCdD     " 
'    aAbBcCdD     '
>typeof unechaine
'string'
>unechaine.toLowerCase()
'    aabbccdd     '
>unechaine.toUpperCase()
'    AABBCCDD     '
>parseInt(100.25)
100
>parseInt("100.25")
100
>unnombre =1234.565789
1234.565789
>unnombre.trim()
... unnombre.trim is not a function

J'applique les méthodes .toUpperCase() & .toLowerCase() à un objet de type String : la variable "unechaine".
Notez la syntaxe : objetString.méthode(). C'est ce qu'on appelle la notation pointée.
Si je tente d'appliquer la méthode trim() à un nombre, j'ai une erreur !

Par contre je peux appliquer la fonction ParseInt() à un nombre mais aussi à une chaine (si cette chaine est au format numérique).
Attention typeof n'est pas une fonction mais un opérateur.

Un script reprenant quelques fonctions prédéfinies et méthodes

Le code du document HTML

J'ai créé une fonction personnelle nommée "mon_script()" qui est appelé par un bouton cliquable.
Dans cette fonction 'perso' j'utilise les fonctions prédéfinies isNaN(), parseInt() & parseFloat().
La fonction isNaN() retourne true si l'argument n'est pas au format numérique.
La fonction inverse(!isNaN()) retourne true si l'argument est au format numérique (suite de chiffres avec un point éventuel).

Attention la valeur retournée par la méthode prompt est toujours de type string même si vous avez saisi une suite de chiffres.
Donc avant d'effectuer des calculs il faut convertir cette valeur en numérique (entier ou décimal) avec respectivement les fonctions parseInt() & parseFloat().

Le rendu dans un Iframe

Saisissez une suite de lettre puis un nombre décimal au format francophone (la virgule en guise de séparateur décimal) : vous restez dans la boucle de saisie.
Saisissez enfin un nombre avec un format correct (le point en guise de séparateur décimal).

À propos de la fonction parseInt()

Cette fonction admet un deuxième paramètre facultatif : la base de conversion; par défaut ce deuxième argument est 10 (décimal).
Test dans la console :

>console.log(parseInt('FE',16))
254
>console.log(parseInt('A9',16))
169
console.log(parseInt('7777',8))
4095

La fonction retourne l'équivalent décimal de 'FE' puis de 'A9' en héxadécimal puis l'équivalent décimal de '7777' en base octal.

Créez ses propres fonctions

Les fonctions génériques et méthodes ne couvrent pas tous les besoins. Vous pouvez donc être appelé à créer et utiliser vos propres fonctions.

Si vous souhaitez utiliser vos fonctions personnelles dans différentes pages web, vous pouvez bien sûr créer un fichier de fonctions : un fichier d'extension .js. C'est d'ailleurs le principe de certaines librairies JS célèbres ...

Fonctions personnelles - niveau 1

Il s'agit d'une fonction 'perso' basique car il n'y a pas de paramètre à passer et cette fonction ne retourne pas de valeur.
Objet de cette fonction basique : calculer la surface d'un cercle de 2 cm de rayon.

Le script

Il se présente sous forme d'une fonction nommée "mon_script()" et appelé par un bouton cliquable.
Instruction HTML:
<button onclick ="mon_script()" > Appel du script </button >

Le script
function mon_script()
{
	function f_cercle() 
		{ 	// fonction qui calcule la surface d'un cercle de rayon 2 cm 
			var vrayon = 2 ; 
			var vsurface = vrayon * vrayon * 3.14 ;
			alert("surface du cercle : " + vsurface + "cm2") ; 
		}
		f_cercle() ; //appel fonction
		f_cercle(); // appel fonction 
		alert("type de f_cercle : " + typeof f_cercle); 
		alert(vrayon); // erreur : vrayon is not defined  
} // fin mon_script

La fonction "mon_script()" comprend deux parties :

Pour définir une fonction il faut utiliser le mot réservé function suivi du nom que vous donnez à cette fonction.
Ici il s'agit d'une fonction basique qui se nomme fsurface_cercle.
Les instructions de la fonction sont délimitées par une paire d'accolades.
Cette fonction calcule la surface d'un cercle de rayon 2cm ; n'y a donc pas d'argument à passer lors de son appel?
La fonction ne se contente pas de calculer la surface du cercle mais affiche le résultat dans une boite de dialogue (méthode alert()).

Le rendu dans un Iframe

Dans la routine principale on appelle deux fois la fonction.
Puis on demande le type de "f_cercle" ; la réponse est "function". Une fonction est en fait une variable de type function.
Puis on demande d'afficher la variable vrayon ; la console affiche le message d'erreur : "vrayon is not defined". En effet vrayon est une variable créée au sein de la fonction donc elle est inconnue de la routine principale.

Toute variable déclarée dans le cadre d'une fonction n'est utilisable qu'au sein de cette fonction. On dit que la variable est locale.

Fonctions personnelles - niveau 2

La fonction de l'exemple précédent était d'un usage des plus limité : calcul de la surface d'un cercle de rayon 2 unités.
Nous allons maintenant définir et utiliser une fonction capable de calculer la surface d'un cercle indépendamment de son rayon et unité de mesure. Il faut alors créer une fonction avec paramètres c'est à dire qu'il faudra saisir un argument (ou des arguments) lors de son appel.

Le script

Il est appelé, comme dans l'exemple précédent, par un bouton cliquable.

function mon_script()
{
	function fsurface_cercle(rayon,unite) 
	{ 
	let surface = rayon * rayon * 3.14 ;
	alert(`surface du cercle  ${surface}  ${unite} carrés`) ; 
	} // fin fonction

// appels de la fonction
		fsurface_cercle(2,"cm") ; // premier appel
		fsurface_cercle(15); // deuxième appel
} // fin mon_script

Notez bien l'argument de la méthode alert() dans la définition de la fonction perso : `surface du cercle ${surface} ${unite} carrés`
J'ai donc utilisé, pour éviter une concaténation fastidieuse, la notation "template strings" ou "littéraux de gabarit".
Pour en savoir davantage sur les littéraux de gabarit

Le rendu

Cette fonction nommée fsurface_cercle calcule la surface d'un cercle quelque soit son rayon et l'unité de mesure (cm ou dm ou décimètre, ...).
Il s'agit donc d'une fonction avec deux paramètres.
Donc dans le cadre de l'appel de cette fonction, il faut indiquer entre parenthèses deux arguments. Or à l'occasion du deuxième appel je ne passe qu'un paramètre et j'obtiens en retour : "surface du cercle 706.5 undefined carrés"

Améliorations de la fonction

function fsurface_cercle(rayon,unite='cm') 
{ 
	let surface = rayon * rayon * 3.14 ;
	alert(`surface du cercle  ${surface}  ${unite} carrés`) ; 
} // fin fonction

Notez la syntaxe : function fsurface_cercle(rayon,unite='cm') : le deuxième paramètre est optionnel et par défaut il vaut 'cm'.
Si, par exemple, l'appel de fonction est : fsurface_cercle(15) le retour est : "surface du cercle 706.5 cm carrés"

Vérifiez vous même :

Fonction personnelle - niveau 3

Vous savez que les fonctions et méthodes natives sont paramétrables mais en plus retournent une valeur.
Créons une fonction personnelles ayant les mêmes caractéristiques !
Pour qu'une fonction retourne une valeur (vers la routine principale) il faut que dans sa définition celle-ci comporte l'instruction return suivie de la variable ou expression à retourner.

Le script

Il est appelé par un bouton de commande comme dans l'exemple précédent.

function mon_script()
{
	let fpuissance2 = function(nombre) 
	{ 	return nombre * nombre ; } 

	alert(fpuissance2(12)); 
	let vnombre = prompt('saisir un entier'); 
	alert(fpuissance2(vnombre)); 
	alert(typeof(fpuissance2));
} // fin mon_script

La fonction se nomme fpuissance2 et exige la saisie d'un argument lors de son appel.

Au lieu d'écrire function fpuissance2(nombre) j'ai écrit let fpuissance2 = function(nombre). Ce qui montre qu'une fonction est en fait une forme particulière de variable.

Le rendu dans un Iframe

La dernière instruction retourne "function" !
Tapez "4O (lettre O au lieu du zéro) et observez ...

La fonction nommée fpuissance2 calcule le carré d'un nombre et retourne une valeur à la routine appelante.
Dans la routine principale j'appelle deux fois la fonction "fpuissance2".

Conversions automatiques

Je rappelle que toute saisie via la méthode prompt() est de type string. Et donc il faudrait convertir la saisie en type "float" ou "int" avant tout calcul.
Or dans le script précédent je ne convertis pas la valeur saisie avant de l'élever au carré ...
En effet en cas de multiplication / division / soustraction la conversion est automatique mais pas en présence de l'opérateur + car dans ce contexte ce symbole signifie concaténation.

Pour vous convaincre, créez et testez le script suivant !

function mon_script()
{
	let fdouble = function(nombre) 
	{ 	return nombre + nombre ; 	} 

	let vnombre1 = prompt('saisir un entier '); 
	alert(fdouble(vnombre1)); 
	let vnombre2 = prompt('saisir un entier ');
	alert(fdouble(vnombre2));
} // fin mon_script

Exécution :
Saisissez 7 ; affichage de 77
Saisissez 25 ; affichage de 2525
Il y a donc bien concaténation et non pas addition puisqu'il s'agit d'objets String.

Le bon code : Insérez dans la fonction l'instruction : nombre = pareseFloat(nombre).

Appel de fonction avec en argument le mot "this"

L'argument passé lors de l'appel d'une fonction peut être le mot réservé this qui désigne l'objet courant.

Thème : obtenir des infos sur les images du document HTML.

Le code HTML

Notez bien la syntaxe : ... onclick ='fafficher(this)' ...
this est un mot réservé de JS très pratique. Il désigne l'élément HTML courant (la cible de la manipulation).

Attention pour qu'une fonction s'applique à l'élément HTML courant il faut employer le mot magique "this" comme argument lors de l'appel de la fonction mais jamais comme paramètre dans la définition de la fonction.
Le nom du paramètre pour la description de la fonction est toujours libre.
Ici j'emploie le terme image puisque la fonction s'applique toujours à un élément IMG.

Le script correspondant

Il se résume à une fonction nommée "fafficher()".
Cette fonction peut s'appliquer à n'importe quelle image de la page du moment qu'elle est l'objet courant.

function fafficher(image)
{
	let chemin = image.src ; 
	let texte = image.alt
	alert(`chemin image :  ${chemin} ` );
	alert (`texte alternatif de l'image :  ${texte} `) ; 
} // fin fonction

Dans la définition de la fonction le paramètre se nomme 'image'.
Dans les instructions de la fonction on retrouve ce terme plusieurs fois : image.src, image.alt.
J'aurais pu avoir aussi : image.width, image.height, image.id, image.title

Le rendu dans un Iframe

Cliquez successivement sur les différentes images !

Il y aurait N images, la fonction "fafficher()" serait strictement identique.

Les fonctions anonymes

Sachez qu'il existe des fonctions sans nom (fonctions anoymes).
Dans une même bloc on décrit et on appelle la fonction.
La syntaxe d'une fonction anonyme sur un évènement est la suivante:

élément.évènement = function() 
	{ 
		instruction1; 
		instruction2;
		... ; 
		instructionN; 
	}

Thèmatique : nous voulons que le visiteur de la page puisse modifier la couleur du texte pour les titres et le paragraphe associé donc pour deux éléments.

Solution traditionnelle : emploi d'une fonction nommée

J'utilise dans le code HTML des attributs événementiels pour appeler à chaque fois la fonction "fcouleur()".

Le rendu du script dans un Iframe

Pour cibler dans le script un élément HTML j'utilise les nouvelles méthodes de l'objet document : querySelector() & querySelectorAll().
Ces deux méthodes acceptent comme argument un sélecteur CSS.
Notre code est tout à fait correct mais présente un inconvénient majeur : encore des "scories JS" dans le code HTML.

Solution moderne : avec des fonctions anonymes

Non seulement je vais utiliser des fonctons anonymes mais de plus je vais centraliser tout le code JS dans le conteneur SCRIPT.

La détection des évènements va se faire via le JavaScript (et non plus via HTML). En d'autres termes j'abandonne le gestionnaire d'évènements HTML pour le gestionnaire d'évènements JS.

Le code HTML

Plus aucune trace de code JS dans le code HTML. Notez que j'ai affecté à chaque bouton un ID ...

Le script

Tout le code JS est regroupé dans le conteneur SCRIPT.

let titre = document.querySelector('h1') ; 
let texte = document.querySelector('p') ; 
document.querySelector('#vert').onclick = function() 
	{titre.style.color = 'green'; texte.style.color = 'green'; }
document.querySelector('#rouge').onclick = function() 
	{ titre.style.color = 'red'; texte.style.color = 'red'; }
document.querySelector('#bleu').onclick = function() 
	{ titre.style.color = 'blue'; texte.style.color = 'blue'; }

J'utilise désormais le gestionnaire d'évènements de JS.
Grâce à la centralisation du code JS, La lisibilité de celui-ci est facilitée.
Pour en savoir plus sur la gestion des évènements en JS : Les évènements

Étudions plus en détail la première fonction anonyme : appelée par un clic

document.querySelector('#vert').onclick = function() : si clic sur le bouton identifié "vert" appel de cette fonction anonyme.

Le rendu dans un Iframe

Solution définitive

Vous pouvez trouver que le script ci-dessus est un peu lourd. Il le serait encore davantage si au lieu de modifier le style de deux éléments HTML, il s'agissait d'en modifier 6 ...
Il serait plus pertinent que chaque fonction anonyme appelle à son tour la même fonction nommée.

Le code HTML - rajouts

Désormais il y un titre et trois éléments de type P. Donc le script doit modifier désormais le DOM pour 4 éléments (et non plus 2) !

Le script

// les fonctions anonymes : 
document.querySelector('#vert').onclick = function() {changer_couleur('green'); }
document.querySelector('#rouge').onclick = function() {changer_couleur('red');}
document.querySelector('#bleu').onclick = function() {changer_couleur('blue'); }

// fonction nommée appelée par l'une des fonctions anonymes : 
function changer_couleur(couleur)
{
	document.querySelector('h1').style.color = couleur ; 
	document.querySelector('p').style.color = couleur; 
	document.querySelectorAll('p')[1].style.color = couleur ; 
	document.querySelectorAll('p')[2].style.color  = couleur ; 
	
} // fin fonction

Chaque bouton appelle une fonction anonyme.

Chaque fonction anonyme appelle la fonction nommée "changer_couleur()" avec passage en argument de la couleur retenue.

Ici la fonction "changer_couleur()" permet de modifier le style de quatre balises (H1 et 3 éléments P). Si je voulais changer 6 éléments du DOM il suffirait de rajouter 2 instructions dans la fonction nommée.

Le rendu

Fonctions autoexécutées

Les fonctions anonymes peuvent s'autoexécuter dans le cadre d'un minuteur ('timer').
Pour créer un 'timer' il faut faire appel aux méthodes (de l'objet window) : setInteval()/setTimeout().

Le code du document HTML

Rappel syntaxique concernant setInterval()

let stop = setInterval ... : lorsque vous utilisez setInterval() cette méthode renvoie un identifiant unique que vous devez stocker dans une variable.
... onclick ="clearInterval(stop) : utilisez la méthode clearInterval() argumentée avec cette variable pour arrêter l'exécution périodique.

Le rendu

La méthode setInterval() exécute la fonction anonyme chaque seconde.
Cliquez sur le bouton de commande pour cesser l'incrémentation.

Fonctions particulières

Fonctions qui retournent plusieurs valeurs

Ces fonctions retournent un 'array' donc plusieurs valeurs.

Le script

function mon_script()
{
	function fcercle(rayon)
	{
		let aire = Math.round(rayon * rayon * 3.14); 
		let circonference = Math.round(rayon * 2 * 3.14) ; 
		let tab =[aire, circonference]; 
		return tab; // retourne un tableau de 2 éléments
	}
 
 	let rayon =parseInt(prompt("saisir le rayon du cercle !")); 
	let tableau =fcercle(rayon);  //appel de la fonction fcercle
	document.write("aire : " + tableau[0]); 
	document.write("circonférence : " + tableau[1]); 
} // fin mon_script

Étudiez bien la fonction. Elle retourne un 'array' avec deux valeurs.
Donc lors de l'appel de fonction la variable d'affectation "tableau" est donc un tableau indicé avec deux éléments ; Le premier élément contient l'aire et le deuxième la circonférence.
Math.round(expression) : méthode de l'objet Math pour arrondir à l'entier le plus proche.

Le rendu dans un Iframe

Fonction flexible : nombre variable de paramètres

Précédemment je vous ai montré comment rendre la saisie d'un ou plusieurs argmuents optionnels en proposant pour ces paramètres une valeur par défaut. Mais il y a mieux encore : fonction qui accepte 2 ou 3 ou 4 ou N arguments lors de son appel.

Thème : créer une fonction qui cumule un nombre variable d'entiers : 2 ou 3 ou 4 ou 5 ou N ... Donc le nombre d'arguments à saisir lors de l'appel de la fonction est variable.

Le script

function mon_script()
{
	function fsomme(...tab)
	{
		let cumul = 0; 
		for (let valeur of tab) 
			{cumul+=valeur ;}
		return cumul; 
	} // fin fsomme

// appels fonction
	let cumul1 = fsomme(10,10,30); 
	let cumul2 = fsomme(1,2,3,4); 
	let cumul3 = fsomme(1000,2000); 
	console.log(cumul1); 
	console.log(cumul2);
	console.log(cumul3);
} // fin mon_script

Dans cette fonction, "tab" est un tableau indicé.
Dans la parenthèse ; le nom de l'objet 'array' doit être précédé de trois points.

Notez les différents appels de la fonction avec 3 puis 4 et enfin 2 arguments.

Le rendu dans un Iframe

Vous voyez apparaitre dans la console : 50 puis 10 puis 3000.

Fonctions fléchées

Avec la dernière version de ECMAScript, il est possible de définir des fonctions avec une syntaxe très simple : la déclaration de la fonction tient en une instruction.
Thème : créer une fonction qui fait la sommme de deux nombres et multiplie le tout par un troisième nombre.

Le script

function mon_script()
{
	let x =10, y = 12, z = 13; w = 14;  
	// ci-dessous fonction nommmée standard
	let fstandard = function(n1,n2,n3) 
		{ return (n1 + n2) *  n3;	};
// fonction anonyme fléchée 
	let fflechee = (n1,n2,n3) => (n1 + n2) * n3;

document.write("
appel fonction standard : " + fstandard(x,y,z)); document.write("
appel fonction fléchée : " + fflechee(x,y,z)); ...

Les fonctions fstandard & fflechee font exactement la même chose.
La première a une syntaxe standard alors que la seconde a un syntaxe simplifiée dite "fléchée".
Dans cette syntaxe simplifiée le mot "function" disparait ; le mot "return" est remplacé par une flèche d'où l'expression "fonction fléchée".

Le rendu dans un Iframe