Algorithmes fonctionnels en javascript sous la forme de cours et d'exercices. Utilisation de js dans un contexte de liste, de map, list_it. Inspiré de caml. A lire à l'envers...

mercredi 3 septembre 2008

Fonctions en javascript

Particularité des Fonctions:


Les fonctions sont des éléments de "première classe", une fonction est un type comme un autre, on peut donc l'échanger à l'aide de son nom ou la retourner.
Pour l'exécuter il faudra utiliser l'opérateur double parenthèse ( ) avec éventuellement des arguments à l'intérieur, on peut ainsi écrire:

var hello = function(){ return "hello";}
div.onclick = hello ;

Ainsi la fonction hello sera exécutée seulement lors du clic de la souris sur l'élément div. Mais la variable hello, du type fonction, peut être manipulée comme toute autre variable. En fait ici on assigne à la variable "hello" une fonction anonyme .
Attention, le mot clé var permet de désigner la portée de la variable déclarée, ainsi si hello est déclarée à l'intérieur d'une autre fonction, elle ne sera pas accessible hors de cette fonction, d'où l'intérêt de cette notation. Si var est omis, alors la portée devient globale même à l'intérieur d'une fonction. Si vous scriptez une page web, le contexte global correspond à l'objet window.
On peut également écrire les fonctions façon java:
function hello(){ return "hello" ;} // comme en java ou php

L'inconvénient ici c'est que la fonction risque d'être écrite dans un contexte global, ce qui doit être banni car il y a risque de collision avec d'autres variables importées par d'autres scripts.
Il existe en outre une façon spéciale de construire une fonction en utilisant le mot clé Function et du constructeur "new" :

var add = new Function("x", "y", "return x+y") ;
add('Hello ', 'World' );// "Hello World"

Dans cette dernière syntaxe, le dernier argument de "Function " est le type retourné. Une des utilisation possible de Function est de décoder des objets transmis suivant la notation JSON par exemple:

var monobjet = "{ langage: 'java' , annee: 1995} " ;// un objet javascript au format JSON.
var obj = Function( "return "+ monobjet)() ;// remarquez l'exécution à l'aide de () ;
obj.annee; //1995

On peut également créer une fonction anonyme et l'exécuter immédiatement à l'aide de l'opérateur () ce qui permet à l'interpréteur javascript de ne pas la garder en mémoire :
(function(){ return "hello world";})() // la fonction est anonyme, elle est exécutée immédiatement.

Une dernière variante consiste à nommer une fonction anonyme qui devient moins anonyme mais ce qui permet de l'appeler récursivement :
(function facto (n){    if (n == 1) return 1 ;
else return n* facto(n-1) ;})(5) ; // 5*4*3*2*1= 120

Valeur retournée par une fonction le mot clé "return " :

Si le mot clé "return" est oublié la fonction retourne par défaut : "undefined".
Par ailleurs il existe des erreurs de conception du langage, ainsi on peut écrire:
if( a==2) return true ; else return false ; //correct

ou
return (a==2)? true : false ; //équivalent

mais pas:
(a==2)? return true: return false; // erreur
ni
(return a==2 || return false) ; // erreur écrire: return (a==2 || 'false' )

En effet l'instruction "return ..." n'est pas évaluée ce qui empêche ce genre d'idiome très utilisé en Perl.

Séparateur de ligne le point-virgule facultatif ; :


Il faut également faire attention au caractère facultatif du point virgule, javascript remplace un retour à la ligne par un point virgule, dans ce cas:

return
true

retourne "undefined" car il est interprété comme return; true ;

Arguments des fonctions, methodes apply et call :


Lors de la définition des fonctions, il est habituel de désigner les arguments de fonctions dans la double parenthèse, or il faut savoir que ces arguments sont facultatifs et qu'ils sont repris par javascript dans un tableau spécial toujours disponible nommé arguments,

function somme(){
var resultat=0 ;
for(var i=0; iresultat += arguments[i] ;
return resultat ;
}
somme(1,3,4); // 8

Attention! Ce tableau arguments, par erreur de conception du langage n'est pas un vrai tableau et il sera parfois nécessaire de le transformer en véritable tableau, en le dupliquant et en utilisant la méthode nouveauTableau = Array.slice(arguments) ;

Apply et call :


On peut parfois appeler une fonction par apply ou call de cette façon:
somme.apply(this, [1,3,4]);
var maximum = Math.max.apply(this,[5,3,10,5]);
var monTableau = [1,4,42,10,7] ;
var maximum = Math.max.apply(null,monTableau);
maximum ; //42

  • le premier argument de correspond à l'objet sur lequel est appelé la fonction.
  • le second argument est un tableau.

On peut également utiliser call, on écrit alors:

somme.call(this, 1,3,4) ; // identique à somme(1,3,4)

Nous avons donc vu ici plusieurs méthodes pour créer une fonction dans un contexte différent des objets .
Le problème du mot clé "return" qui peut être omis.
La variable cachée arguments et les méthodes "apply et call" pour utiliser un nombre indéfini d'arguments.
On voit donc que l'écriture classique des fonctions javascript façon java est le résultat d'un
camouflage de variable et de méthodes.

Aucun commentaire: