Cours d'introduction à JavaScript

par Patrick TRAU

1) justification

On me demande assez souvent comment mettre, dans sa page web, un petit programme de calcul.

S'il est écrit dans une langage classique comme C++ ou Pascal, on peut fournir (à télécharger) une version compilée de notre programme, qui pourra tourner uniquement sur un système compatible avec le notre (et surtout chez les inconscients qui se croient immunisés contre les virus), ou fournir le source, le destinataire devant alors posséder un compilateur de ce langage, savoir comment compiler, et surtout n'avoir utilisé aucune spécificité de notre compilateur (dans la pratique, cela revient généralement à rester en mode texte : MS-Dos, console Unix...)

A l'opposé, il y a la solution d'utiliser Java, qui est effectivement efficace et multi-plateforme. C'est un langage orienté objet, ressemblant au C++, mais nécessitant un apprentissage non négligeable, si l'on veut s'en servir réellement (gestion des interfaces, évênements, threads...).

Pour celui qui connait le C (normalement, tous mes étudiants) une solution simple est JavaScript. Du moins tant qu'on se limite à des programmes pas trop complexes (ce n'est pas que JavaScript n'y arrive pas, mais pour un programe méritant un effort important, autant choisir un autre langage).

Donc, ce document s'adresse uniquement à qui connait C, et désire insérer dans sa page HTML un petit programme de calcul. Pour un cours complet sur JavaScript, je vous propose deux excellents sites en en français : le cours de Jean Gourdin (académie de Créteil), auquel il ne manque qu'une table des matières, et le-webmestre.net (un peu moins pédagogique), avec de très bons liens vers d'autres sites sur Javascript.

2) les bases du langage

2.1) les instructions : faites comme en C

les instructions sont comme en C, terminées par un point-virgule (bien que non obligaoire). On y trouve des affectations (variable=calcul;), des appels de sous-programme (fonction(arguments)), des structures de contrôle (for, if - else, while, do - while, switch). Les instructions peuvent être regroupée en un bloc (entre accolades), mais les déclarations ne doivent pas obligatoirement se trouver en début de bloc.

2.2) Les variables simples et string

Les variables simples ne doivent pas nécessairement être déclarées, mais c'est préférable (sinon on a une différence de portée par rapport au C, elles deviennent globalement visibles à partir de leur première affectation, mais la meilleure solution pour une variable globale est de la déclarer avant la première fonction). On les déclare par var nomDeLaVariable; sans indiquer de type. Le type est en fait déterminé par la première affectation, et peut même être changé en cours de vie de la variable (mais franchement, c'est une très mauvaise idée). Pour les identificateurs (noms), comme en C, il y a différence entre majuscules et minuscules. Les types simples sont les chaînes de caractères (string), les entiers, réels, et booléens. Les opérateurs sont les mêmes qu'en C (à part pour les string).

Pour les string, l'opérateur + correspond à la concaténation. Attention, JavaScript transforme assez facilement un nombre en string ( 12+"h" donne "12h" et dans certains cas 1+1 donne "11"). Pour transformer explicitement une chaîne contenant des chiffres en nombre, il faut utiliser parseInt(str) ou parseFloat(str). eval("10*(5+1)")quand à lui va rendre 60. A l'inverse, nb.toString(base) transforme nb en chaîne, dans la base donnée (10 ou 16 par ex).

Une chaine ch peut utiliser les méthodes et propriétés suivantes ch.length, ch.substring(pos_debut,pos_fin) (sous chaîne, de debut compris à fin non compris), ch.toUpperCase(), ch.charAt(i) (i-ème caractère), ch.indexOf(sch) donne la position de la première occurence de sch dans ch.

Pour les nombres on dispose de la bibliothèque Math : Math.sqrt(), Math.pow(base, exposant), Math.log(), Math.exp(), Math.abs(), Math.cos (), Math.sin(), Math.tan()
Math.floor(), Math.ceil(), Math.round() entier immédiatement inférieur / supérieur / plus proche.
Math.random() nombre aléatoire dans [0 , 1[

2.3) les tableaux

On les déclare par var nomtab = new Array[nb]; ou même en les initialisant var cartes = new Array("carreau", "pique", coeur", "trefle"); (voire même un tableau d'éléments de type différent). Une matrice est déclarée par var mat=new Array(nb); pour donner le nb de lignes puis (dans une boucle for par ex) un mat[i]=new ... par ligne.

Les indices commencent aussi à 0. un tableau tab possède les méthodes et propriétés tab.length, tab.sort(), tab.reverse()

2.4) les fonctions

l'entête est function nom(noms_des_arguments), on ne donne ni le type retourné, ni le type des arguments (qui sont locaux, comme en C). Elles peuvent aussi être récursives. A part ça, pas de différence avec le C.

2.5) plus encore

évidement je n'ai pas tout défini ici, mais ça va suffire pour l'instant. Sinon, il y a de très nombreux sites disponibles (et d'excellents livres).

2.6) et qu'est-ce qui ne marche pas ?

il n'y a pas de précompilation (ni #define, ni #include). Y compris pour stdio.h, on va voir plus loin comment faire des entrées sorties. Les objets ont des caractéristiques limitées par rapport à C++. Il n'y a pas d'accès au coeur du matériel.

3) interaction JavaScript - HTML

3.1) programme non interactif

il faut écrire son programme entre les balises <SCRIPT language="JavaScript"> et </SCRIPT>. Une méthode (simple) est de le placer exactement dans la page (dans BODY) à l'endroit qui nous intéresse. La portion de HTML produite par le script est envoyée à la page par la methode "document.write"

code que j'ai écrit dans la colonne ci-contreRésultat
  
	<P> voici les 30 premières puissances de 2 : </P>
	<SCRIPT language="JavaScript">
	  var p=1;
	  for(var i=0;i<30;i++) 
	   {
	   p*=2;
	   document.write(p + "<br>");
	  }
	</SCRIPT> 

	

voici les 10 premières puissances de 2 :

Cliquez ici pour voir une page contenant ce code. Si vous demandez à votre navigateur de vous afficher la source de cette page, il va vous montrer le résultat du script (une suite de nombres séparés par des balises <BR>). Mais si vous désirez malgré tout voir la vraie source de la page, cliquez là. Remarque : la page actuelle reste sur votre bureau, les exemples sont dans des fenêtres placées par dessus.

3.2) organisation préférée

En fait, on conseille généralement de mettre les scripts (décomposés en fonctions) dans l'entête (HEAD) du document. Mettez donc :

	<SCRIPT language="JavaScript">
	function puissancesDe2(combien)
	 {
	  var p=1;
	  for(var i=0;i<combien;i++) 
	   {
	    p*=2;
	    document.write(p + "<br>");
	   }
	 }
	</SCRIPT> 
juste devant votre balise de fermeture de l'entête (</HEAD>), et rajoutez dans le corps :
	<P> voici les premières puissances de 2 : </P>
	<SCRIPT language="JavaScript">puissancesDe2(30);</SCRIPT> 
Ceci rendra votre page plus simple à lire, et surtout, vous l'avez surement remarqué, vous permetra de modifier facilement le nombre de puissances affichées (je les ai passées en argument).

Cliquez ici pour voir la page contenant ce code. Pour voir la vraie source de la page, cliquez là.

3.3) réécriture complete de la fenêtre

Mais peut être aimeriez vous que le script, au lieu de s'inscrire dans la page, l'efface et la réécrive totalement. Pour cela, je vous propose cette fonction :

function modif_fen_actu(result)
 {
  document.clear();
  document.writeln("<HTML>");
  document.writeln("<HEAD>");
  document.writeln("  <TITLE>résultat de votre programme</TITLE>");
  document.writeln("</HEAD>");

  document.writeln("<BODY bgcolor=\"#FFFFBB\" background=\"/img/fond-var.gif\">");
  document.writeln("<H1 align=\"center\">résultat programme javascript</H1>");
  document.writeln("<P>votre résultat est <B>");
     document.writeln(result);  //ou toute autre suite de writeln correspondant à votre programme
  document.writeln("</B>.</P>");
  document.writeln("<HR><P align=\"right\">page crée par JavaScript</P>");
  document.writeln("</BODY></HTML>");
  document.close(); //ne pas oublier le close !
 }

ou même dans une nouvelle fenêtre :

function cree_fen(result)
 {
  var fen = window.open("","fen",""); //virer le 3ème argument pour une fenêtre avec tous ses menus
  fen.document.clear();
  fen.document.writeln("<HTML>");
  fen.document.writeln("<HEAD>");
  fen.document.writeln("  <TITLE>résultat de votre programme</TITLE>");
  fen.document.writeln("</HEAD>");

  fen.document.writeln("<BODY bgcolor=\"#FFFFBB\" background=\"/img/fond-var.gif\">");
  fen.document.writeln("<H1 align=\"center\">résultat programme javascript</H1>");
  fen.document.writeln("<P>votre résultat est <B>");
     fen.document.writeln(result);  //ou toute autre suite de writeln correspondant à votre programme
  fen.document.writeln("</B>.</P>");
  fen.document.writeln("<HR><P align=\"right\">page crée par JavaScript</P>");
  fen.document.writeln("</BODY></HTML>");
  fen.document.close();
 }

3.4) Programme intéractif

En général, on préfère commencer un programme par la saisie d'un certain nombre de données. Pour cela, il n'est pas possible d'utiliser comme en C des fonctions du type scanf. Il existe en fait deux possibilités :

Ecrivons un petit programme, dans ces deux approches : il demande deux valeurs (prix et quantité) et calcule le produit des deux (prix total). Dans un premier temps, nous n'effectuons aucune vérification de validité des données.

3.4.1) version séquentielle

En séquentiel, on demande les données par la fonction prompt("texte de la question", valeurParDéfaut);. La valeur saisie est retournée, il suffit de l'affectér à la variable désirée. Pour afficher un message, on appelle la fonction alert("texte du message");. Dans les deux cas le texte peut être une concaténation de variables (voir l'exemple). Le script sera déclanché par un click sur un lien de type <A HREF="JavaScript:appel_de_fonction(args);">

séquentiel (code source)résultat
<HTML>
<HEAD>
  <TITLE>test javascript n°1 - séquentiel</TITLE>
  <SCRIPT language="JavaScript">
  function main()
   {
    var pu = prompt("prix unitaire ?",0); 
    var q = prompt("quantite ?",0);   
    var tot=pu*q;
    alert("ce qui fait " + tot + " en tout ! \nmerci");
    }
  </script>
</HEAD>

<BODY bgcolor="#FFFFBB" background="/img/fond-var.gif">
<H2 align="center">version séquentielle</H2>

<P><A HREF="JavaScript:main();">Lancer le programme</A></P>

</BODY>
</HTML>

 version séquentielle 

Lancer le programme

Cliquez ici pour voir (indépendament) la page contenant le séquentiel. Pour voir la source de la page, cliquez là.

3.4.2) utilisation de formulaires

Pour les formulaires, il existe de nombreuses possibilités. Je vais vous en traiter quelques unes dans ce cours, commençons par un champs simple : <INPUT type="text"> le type est "text" même pour des nombres. On peut définir la taille (size) en nb de caractères, une valeur par défaut (value) mais surtout un nom (name). On en profite pour créer un bouton qui déclanchera le script, c'est plus beau. Le bouton : <INPUT type="button"> sera marqué du texte donné dans "value", mais surtout "onClick" donne la fonction javascript à appeller lorque l'on clique sur le bouton (il existe de nombreuses autres options non traitées ici). Ici, j'ai nommé l'ensemble du formulaire "in_out", nom que je transmets à ma fonction. Dans la fonction, on récupère une valeur de champs par nom_formulaire.nom_champ.value (ici, le nom "in_out" est récupéré dans l'argument formel "formulaire").

avec formulaire (code source)résultat
<HTML>
<HEAD>
  <TITLE>test javascript n°1 - formulaire</TITLE>
  <SCRIPT language="JavaScript">
  function main(formulaire)
    {
        var pu = formulaire.prix.value; 
        var q = formulaire.quantite.value;   
        var tot=pu*q;
        formulaire.total.value = tot ;
    }
</script>
</HEAD>

<BODY bgcolor="#FFFFBB" background="/img/fond-var.gif">
<H2 align="center">version formulaire</H2>
<FORM name="in_out"> 
  <TABLE border=0>
   <TR><TD>prix unitaire : </TD><TD>
   <INPUT type="text" size="10" name="prix"></TD></TR>
   <TR><TD>quantité : </TD><TD>
   <INPUT type="text" size="10" name="quantite"></TD></TR>
   <TR><TD>prix total </TD><TD>
   <INPUT type="text" size="10" name="total" value=" -------- "></TD></TR>
  </TABLE>
  <P><input type="button" value="Lancer le calcul" onClick="main(in_out)"></P>
</FORM>
</BODY>
</HTML>

 version formulaire 

prix unitaire :
quantité :
prix total

Pour voir (indépendament) cette page utilisant un formulaire cliquez ici. Pour voir la source de la page, cliquez là.

3.4.3) versions améliorées

Mais bien sur, il faudrait améliorer ces programmes en verifiant la cohérence des données : vérifier si les champs ne sont pas vides, s'il ne contiennent que des nombres positifs... Je vous les propose ici, en version séquentielle (voir le source), ou avec un formulaire (voir le source). Ils me semblent assez simples à comprendre , je ne donne pas plus de détails.

4) plus sur les formulaires

Nous allons ici améliorer notre programme (version formulaire) en testant d'autres possibilités des formulaires. Le plus simple est que vous l'ouvriez, le testiez et regardiez le source. J'en ai profité également pour utiliser quelques objets et méthodes prédéfinis en JavaScript (gestion de la date, nb aléatoire...)

5) exemple final : le jeu de plus ou moins

C'est un programme que je donne toujours à faire aux étudiants débutants en C. C'est donc tout naturel que je me serve de cet exemple ici. Le programme doit choisir un nombre aléatoire, puis proposer à l'utilisateur de le découvrir, en :

Le plus simple serait que vous l'ouvriez, le testiez et regardiez le source. Manque de chance, en période de TP ce fichier est caché pour que que les étudiants puissent réfléchir un peu. Pour comparer, vous pouvez aussi regarder le source en C.


Patrick Trau, UFR P&I, Université de Strasbourg, mai 2002