Up First Previous

JavaScript Vs ECMAScript

Next Last

Le JavaScript est un langage de script très similaire au C/C++. Créé par Sun Microsystems et Netscape en 1995 et présent depuis la version 2.0 du navigateur de ce dernier, JavaScript (appelé LiveScript au début) est devenu incontournable lors de la création d'un site web interactif. Ses principaux avantages sont de ne pas être exigeant en ressources serveur puisque l'exécution des scripts se fait du côté client (contrairement aux cgi par exemple), et de ne pas appartenir à une firme quelconque (VBScript appartient à Microsoft et ne fonctionne qu'avec Internet Explorer).

 Insertion de code JavaScript 

Le JavaScript est un langage interprété, donc exécuté au fur et à mesure de la lecture de la page par le navigateur. Bien sûr, le code d'une fonction n'est exécuté que lorsqu'elle est appelée, soit plus bas dans le script (ou dans un autre), soit en fonction des actions de l'utilisateur : clic sur un lien (<a href="javascript:ma_fonction()"> ...</a>) ou au déclenchement d'un événement.
En effet, du code JavaScript peut-être introduit de quatre manières dans une page XHTML :

  • Entre des balises de script :

      <script type="text/javascript" language="JavaScript">
      <!--

          mettre ici le contenu du script
      //-->
      </script>

    Un script peut-être déclaré dans la partie d'en-tête (head, généralement des fonctions), ou dans le corps de la page (body, généralement des appels aux fonctions définies en en-tête).

    Les balises de commentaire offrent une sécurité contre des signalements d'erreurs sur les vieux navigateurs ne reconnaissant pas le JavaScript.

    Utiliser les spécificateurs type et language peut paraître redondant mais cela assure la compatibilité avec les différents navigateurs et leurs nombreuses versions.

  • Avec un script externe :


    Il est possible d'externaliser un script et de mettre son code dans un fichier qui sera chargé en même temps que la page XHTML. Pour cela, on utilise l'attribut src="" pour indiquer à la balise script l'adresse du script comme on l'aurait fait pour une image. Ceci est par exemple utile pour un script servant dans plusieurs pages puisqu'il sera alors mis en cache par le navigateur et n'aura pas à être rechargé :
    <script type="text/javascript" language="JavaScript" src="monscript.js"></script>
    On utilise une balise fermante </script> plutôt que la notation <script ... /> pour éviter des conflits éventuels avec des scripts PHP.
  • Associé au pseudo-protocole javascript :

      <a href="javascript:code_JavaScript" />...<balise>

    Comme http ou ftp, le mot clef javascript défini ici un (pseudo-)protocole.

  • Associé à un événement géré par une balise :

      <balise onEvenement="code_JavaScript" />
        ou
      <balise onEvenement="code_JavaScript">...<balise>

    Le code est exécuté lorsque l'événement en question se déclenche.

    Se référer aux événements pour plus de détails.

 Syntaxe du JavaScript 

Le cadre du JavaScript étant défini, nous pouvons désormais nous intéresser à la syntaxe de ce langage qui est quasi similaire à celle du C/C++ dont il est dérivé :

attention ! Attention à la casse, JavaScript fait la différence entre les minuscules et les majuscules !

haut   Les commentaires

Comme en C/C++, des commentaires peuvent être inclus dans du code JavaScript à l'aide des opérateurs // et /* */ :
  // ce qui suit sur cette ligne est en commentaire
  /* ce qui est placé entre ces marqueurs est en commentaire */

Il est fortement conseillé de documenter au moins les déclarations de variables et de fonctions afin d'en clarifier le rôle pour les programmeurs (ou correcteurs !) qui reliront votre code.

haut   Les variables

Les variables sont déclarées à l'aide du mot réservé var sans en préciser le type qui sera déduit des valeurs qui leurs seront affectées. JavaScript n'est pas un langage explicitement typé et le type de ses "objets" peut varier au fil des opérations qui les impliquent.

  var ma_var; // ma_var est de type undefined tant qu'aucune valeur ne lui est affectée
  var res_test = true; // res_test est de type Boolean
  var i = 7; // i est de type Number
  var pi = 3.1415; // pi est de également de type Number
  var semaine = new Array( "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi", "dimanche");
  var jour = semaine[0];
// jour est de type String (chaîne de caractères) et a pour valeur "lundi", celle de la cellule d'indice 0 du tableau semaine.

Les noms de variables ne doivent pas commencer par un chiffre ni contenir d'espaces mais peuvent être composés de la plupart des caractéres alphanumériques (y compris _ et $ depuis JavaScript 1.3). Un nom de variable ne peut pas être un des mots réservés de JavaSCript (var, function, return, if, ...).

Les résultats de tests sont de type Boolean et prennent la valeur vraie (true) ou faux (false).

Il existe un unique type pour les nombres (Number) qu'ils soient entiers (7) ou flottants (3.1415), très grands (9.99e369) ou très petits (1e-369).
Le type NaN, acronyme de Not A Number, est indissociable du type Number. Une variable deviendra de ce type si elle est par exemple le résultat d'une division par zéro. Cet état peut être testé à l'aide de la fonction isNaN : isNaN(1/0) vaut true.
Le type Infinity est celui des nombrs trop grands ou trop petits.
La fonction isFinite permet de s'assurer qu'une grandeur est bien un nombre fini, elle renvoit donc false pour NaN et Infinity.
attention ! Attention, NaN et Infinity ont été introduits dans JavaScript 1.3, pour les utiliser avec des versions inférieurs de JavaScript, il faut les redéfinir :
  var NaN = 1 / 0;
  var Infinity = 1e500 * 1e500;

Contrairement au C/C++, il n'est pas nécessaire de gérer la libération de la mémoire allouée dynamiquement à l'aide de new.

Nous reviendrons sur les variables dans la section sur la portée des variables et les conversions de types.

attention   Les tableaux

Un tableau est un objet de type Array défini à l'aide du mot réservé new : var tab = new Array();. Comme en C/C++, l'indice de la première cellule d'un tableau est 0, mais pour le reste, la gestion des tableaux est beaucoup plus souple en JavaScript :

  • utilisation classique :

    var tab = new Array(3); // on spécifie la taille du tableau
    tab[0] = "je suis la première cellule";
    tab[1] = "je suis la deuxième cellule";
    tab[2] = "je suis la troisième cellule";

    Rien n'empèche de spécifier une taille de tableau supérieure à la taille nécessaire, la mémoire est alors réservée et sera utilisée en cas de besoin.
    Si la taille indiquée n'est pas suffisante, le tableau sera agrandit automatiquement de manière totalement transparente.
  • utilisation pratique numéro 1 :

    var tab = new Array("je suis la première cellule", "je suis la deuxième cellule";, "je suis la troisième cellule");
    L'affectation des cellules se fait lors de la création du tableau, la taille est définie implicitement.
  • utilisation pratique numéro 2 :

    var tab = new Array(); // on ne spécifie pas la taille du tableau
    tab[2] = "je suis la troisième cellule";
    // on ne défini pas les cellules dans l'ordre
    tab[0] = "je suis la première cellule";
    tab[1] = "je suis la deuxième cellule";
  • utilisation pratique numéro 3 :

    var tab = new Array();
    tab[] = "je suis la première cellule";
    // on ne spécifie pas l'indice d'insertion (le dernier + 1, 0 par défaut)
    tab[] = "je suis la deuxième cellule";
    tab[] = "je suis la troisième cellule";
  • utilisation valide mais risquée :

    var tab = new Array();
    tab[23] = "je suis la première cellule";
    tab[69] = "je suis la deuxième cellule";
    tab[48] = "je suis la troisième cellule";

    Seules ces cellules sont définies ! Ainsi, tab[0] est undefined. Cette notation peut être utile pour associer des cellules à des valeurs connues par ailleurs et qui ne sont pas consécutives, cependant elle est problématique pour une utilisation du tableau dans une boucle.
    Lorsqu'un besoin de ce genre de notation se fait sentir, il est préférable d'aller voir du côté des tableaux associatifs.

Tableaux associatifs

JavaScript permet également d'utiliser des tableaux associatifs, c'est-à-dire des tableaux dont les indices ne sont pas des entiers mais des chaînes de caractères organisées dans une table de hachage. L'indice qui est une chaîne de caractères est alors appelé clef, el la valeur qui lui est associée peut être obtenue comme précédemment : var val = tab[clef];.
   var tab = new Array();
   tab["clef 1"] = "je suis la première cellule";
   tab["clef 2"] = "je suis la deuxième cellule";
   tab["clef 3"] = "je suis la troisième cellule";
   var val2 = tab["clef 2"];
// val2 vaut "je suis la deuxième cellule"

Tableaux multi-dimensionnels

Tous les exemples préceacute;dents utilisent des cellules dont les valeurs sont de type String mais il est possible de définir des tableaux dont les cellules sont de n'importe quel type : Number, Boolean et même Array. Dans ce dernier cas on défini un tableau multi-dimensionnel :
   var tab = new Array();
   tab[0] = new Array("lundi",
/* ... */, "dimanche");
   tab[1] = new Array("janvier",
/* ... */, "décembre");
   var mois = tab[1][5];
//mois vaut juin (les indices commencent à 0)

Nombre d'éléments d'un tableau

Les tableaux sont particulièrement propices à une utilisation avec des boucles. Pour cela, la propriété length sera précieuse puisqu'elle représente le nombre d'éléments d'un tableau : var nb_elts = tab.length;. Il s'agit d'une propriété de l'objet Array, il ne faut donc pas mettre de parenthèses !
attention ! Attention, en fait length n'est pas véritablement le nombre d'éléments d'un tableau mais l'indice de sa dernière cellule augmenté de 1. Ainsi, dans l'exemple d'utilisation valide mais risquée présenté plus haut, tab.length vaut 70 = 69+1 et non pas 3 ! Les tableaux associatifs ne connaissent pas ce problème.

haut   Les chaînes de caractères

Une chaîne de caractès est simplement un tableau de caractéres défini à l'aide du délimiteur ". Tous les caractères alphanumériques sont autorisés, y compris ". Pour inclure le caractère " dans une chaîne, on utilise le caractère d'échappement \ : "je suis une \"chaîne\" contenant trois caractères \" grâce au caractère d'échappement \\".
Vous l'aurez sans doute remarqué, il y a deux caractères \ à la fin de la chaîne. En effet, s'il n'y en avait qu'un, il aurait joué le rôle de caractère d'échappement pour le dernier ", le fait de le doubler à annuler cette action.
Voici les caractères particuliers les plus classiques :

  • \" est un guillemet
  • \\ est un antislash
  • \n est un retour à la ligne
  • \r est un retour chariot
  • \t est une tabulation

Il existe de nombreuses fonctions dédiées à la gestion des chaînes de caractères. A l'instar de la programmation objet, ces fonctions peuvent être vues comme des fonctions membres d'objets de classe String et sont donc utilisées simplement de la façon suivante : var ma_chaine = "bla bla"; ma_chaine.fonction_membre(/* arguments */);.

  • indexOf(/* un caractère */) : renvoit l'indice (entre 0 et length) de la première occurence du caractère passé en argument.
    renvoit -1 si le caractère n'est pas présent dans la chaîne.
  • bla : bla

en travaux ! A FINIR

haut   Les fonctions

Les fonctions sont simplement déclarées à l'aide du mot réservé function :
  function sans_argument() { /* ... */ [return [valeur];] }
  function avec_arguments(var arg1, var arg2) {
/* ... */ [return [valeur];] }

Comme les variables, les arguments de fonctions ne sont pas explicitement typés. Une différence cependant, ils ne sont pas précédés du mot réservé var.

Le type de retour des fonctions n'est pas indiqué non plus.

attention ! Attention, contrairement au C/C++, il n'est pas indispensable d'affecter une valeur à chacun des arguments d'une fonction lors d'un appel. Charge au code de cette fonction de vérifier que tous les arguments indispensables ont bien une valeur valide avant d'effectuer des traitements.

haut   Les opérateurs

  • Opérateurs arithmétiques (et de concaténation) 

    • + effectue l'addition de deux nombres ou la concaténation de deux chaînes de caractères
    • - effectue la soustraction de deux nombres
    • * effectue la multiplication de deux nombres
    • / effectue la division (flottante) de deux nombres
    • % renvoit le reste de la division entière de la première opérande par la seconde (modulo)
  • Opérateurs d'incrémentation/décrémentation et d'affectation 

    • ++ effectue une incrémentation (opérateur unaire)
    • -- effectue une décrémenation (opérateur unaire)
    • += rajoute la valeur de la seconde opérande à la première (concaténation pour des chaînes de caractères)
    • -= enlève la valeur de la seconde opérande à la première
    • *= affecte à la première opérande la valeur de sa multiplication par la seconde opérande
    • /= affecte à la première opérande la valeur de sa division par la seconde opérande
    • %= affecte à la première opérande la valeur de son modulo par la seconde opérande
    • |= cf. les opérateurs de bits ci-dessous
    • ^= cf. les opérateurs de bits ci-dessous
    • &= cf. les opérateurs de bits ci-dessous
    • <<= cf. les opérateurs de bits ci-dessous
    • >>= cf. les opérateurs de bits ci-dessous

    Pour tous ces opérateurs, la première opérande (seule pour ++ et --) doit être une variable !
    D'autre part, ++ et -- peuvent être postfixés ou préfixés

  • Opérateurs relationnels 

    • == teste l'égalité (fonctionne aussi avec des chaînes de caractères)
    • == teste l'égalité stricte : comparaison des valeurs et des types (7 et "7" ont même valeur mais ne sont pas de même type)
    • != teste la différence
    • != teste la différence stricte (cf. égalité stricte)
    • < et <= testent l'infériorité
    • > et >= testent la supériorité
  • Opérateurs logiques 

    • ||  ou logique (inclusif)
    • &&  et logique
    • !  non logique
  • Opérateurs de bits 

    • |  ou inclusif
    • ^  ou exclusif
    • &  et
    • ˜  non
    • <<  déplacement à gauche
    • >>  déplacement à droite

haut   Portée des variables et conversions de types

Par défaut, les variables ont une portée locale, c'est-à-dire qu'une variable définie dans une fonction ne peut être utilisée en dehors de cette fonction. A contrario, une variable définie hors d'une fonction peut être utlisée dans tout le programme (y compris dans un autre script) du moment qu'une valeur lui a été affectée avant qu'elle ne soit utilisée.

en travaux ! Pour les problèmes de conversions de types, reportez-vous à cette page.

haut   Les tests

La commande if s'utilise simplement :
  if ( /* condition vraie */ )
   {
/* ... */ }
  
[ else // dans le cas contraire
   {
/* ... */ }]
La partie else est optionnelle.
Les blocs if else peuvent étre imbriqués les uns dans les autres.

Lorsque les traitements se bornent au retour d'une valeur en fonction du résultat d'un test (par exemple pour obtenir le minimum de deux valeurs), il est possible d'utiliser la notation suivante :
  var mini = (a<b) ? a : b;

Lorsque l'on veut définir plusieurs traitements selon la valeur d'une variable, on utilise la syntaxe suivante :
  switch ( /* variable à tester */ )
  {
     case /*
valeur_1 */ :
      
/* traitement 1 */
       break;
    
/* ... */
     case
/* valeur_N */  :
      
/* traitement N */
       break;
     default :
// dans tous les autres cas
      
/* code par défaut */
       break;
  }

Les commandes break; qui terminent les traitements de chacun des cas ne sont pas obligatoires, mais si elles ne sont pas présentes, le code qui suit est exécuté jusqu'à la rencontre d'un break; sans tester à nouveau la valeur de la variable !
Contrairement au C/C++, il est possible d'utiliser la commande switch sur des variables d'autres types qu'entier. Il est ainsi tout à fait valide d'utiliser cette notation pour définir des traitements fonctions de la valeur d'une chaîne de caractéres.

haut   Les boucles

La boucle while (Tant que) est très simple :
  while (/* condition vraie */)
   {
/* corps de la boucle */ }
Il faut faire attention que la boucle ne soit pas infinie, et donc que la condition qui est testée à chaque itération puisse prendre (suite aux traitements du corps de la boucle) la valeur false afin que l'on quitte la boucle.

Comme en C/C++, la boucle for ne constitue qu'une écriture plus simple (dans la plupart des cas) d'une boucle while :
  for(/* initialisation */; /* condition vraie */; /* incrémentation */)
   {
/* ... */ }
L'utilisation la plus courante est le parcours d'un tableau :
  for(i=0; i<tab.length; ++i)
   {
/* traitement sur tab[i] */ }
Il est possible de sauter à l'itération suivante avec la commande continue; ou au contraire de quitter brusquement la boucle avec une commande break; mais ceci est fortement déconseillé car source d'erreurs, d'autant qu'il est toujours possibles de procéder autrement.

La boucle do while est une boucle while dont le corps est exécuté au moins une fois :
  do { /* corps de la boucle */ } while (/* condition vraie */);
Attention à ne pas oublier le ; après le test du while.

haut   Écriture de code XHTML

Pour construire une partie du document XHTML depuis un JavaSript, on utilise les commandes document.write(' code XHTML '); et document.writeln(' code XHTML '); où le suffixe ln indique l'ajout d'un saut de ligne à la fin de l'insertion de code XHTML.
document est un des objets définis dans le DOM (Document Object Model) que nous étudierons dans le prochain cours, il représente la page XHTML en construction.

 Les objets Javascript 

En JavaScript, les notions d'objet et de type se recoupent parfois. Nous avons ainsi déjà identifié les objets Array, String et Number. En programmation objet, on pourrait les définir comme des classes dont les variables de ce type seraient des instances. Ainsi, ils contiennent des propriétés (comme length pour Array) et des fonctions membres (comme indexOf pour String).

Nous allons étudier ici d'autres objets JavaScript qui ne sont pas des types :

  • Les propriétés et fonctions de l'objet Math :

    • pi : constante de valeur 3.1415...
    • sqrt() : renvoit la racine carré
    • cos(), sin(), tan() : fonctions trigonométriques (angles en radians)
    • acos(), asin(), atan() : fonctions trigonométriques incerses
    • min(a,b) : renvoit le minimum de a et de b
    • max(a,b) : renvoit le minimum de a et de b
    • pow(x,n) : renvoit la puissance n-iegrave;me de x
    • random() : renvoit un nombre aléatoire entre 0 et 1

 Les événements Javascript 

Le tableau ci-dessous présente les événements JavaScript (informations récupérées sur allhtml.com). Pour leur utilisation, retournez voir les méthodes d'insertion de code JavaScript dans un document, ou reportez-vous aux exemples à la fin de cette section.

Événement Balises Action de déclenchement Compatible depuis
onAbort body, frameset L'utilisateur interrompt le chargement d'une page NN3 et IE4
onAfterUpdate presque toutes les balises Lorsque le contenu d'un formulaire à changé IE4
onBlur label, input, select, textarea, button Un élément n'est plus sélectionné avec le clavier NN3 et IE3
onChange input, textarea Un élément est désélectionné et a été modifié NN3 et IE3
onClick presque toutes les balises L'utilisateur clique sur un élément NN3 et IE3
onDblClick presque toutes les balises L'utilisateur double-clique sur un élément NN3 et IE4
onError presque toutes les balises Un élément n'a pas été chargé NN3 et IE4
onFocus label, input, select, textarea, button Un élément est sélectionné avec le clavier NN3 et IE3
onHelp presque toutes les balises L'utilisateur appuie sur la touche F1 (aide) IE4
onKeyDown presque toutes les balises L'utilisateur appuie sur une touche sur un élément NN3 et IE3
onKeyPress presque toutes les balises L'utilisateur appuie, puis relâche une touche NN3 et IE3
onKeyUp presque toutes les balises L'utilisateur relâche une touche sur un événement NN3 et IE3
onLoad body, frameset Le navigateur ouvre la page HTML NN3 et IE3
onMouseDown presque toutes les balises L'utilisateur appuie sur le bouton de la souris NN4 et IE4
onMouseMove presque toutes les balises L'utilisateur déplace la souris sur un élément IE3
onMouseOut presque toutes les balises L'utilisateur fait ressortir la souris d'un élément NN3 et IE4
onMouseOver presque toutes les balises L'utilisateur place la souris sur un élément NN3 et IE3
onMouseUp presque toutes les balises L'utilisateur relâche le bouton de la souris NN4 et IE4
onReadyStateChange form La page se charge IE4
onReset form Un formulaire est réinitialisé NN3 et IE3
onResize body L'utilisateur redimensionne la fenêtre du navigateur NN3 et IE4
onScroll body L'utilisateur se sert des barres de défilement de la page IE4
onSelect input, textarea L'utilisateur sélectionne du texte NN3 et IE3
onSubmit form Un formulaire est envoyé NN3 et IE3
onUnLoad body, frameset Le navigateur ferme la page HTML NN3 et IE3

A titre d'exemple, l'affichage du code couleur dans la rubrique "couleurs" du cours sur les feuilles de style se fait grâce à l'événement onMouseOver sur chaque balise td des tableaux.
La partie exemples présente quelques scripts classiques.

 Exercices pratiques 

Voici un ensemble de petits exercices pratiques qui vous aideront à assimiler le langage JavaScript :

  1. Ecrire une fonction EurosFrancs qui transforme un montant en euros (passé en argument) en francs puis renvoit cette valeur.
    Ecrire également une fonction effectuant la transformation inverse.
  2. A l'aide de la fonction findObj(id) présentée dans le cours sur le DOM, écrire une fonction ChangeImage(id,srcnew,titlenew) qui modifie une image d'identifiant id pour la remplacer par l'image d'adresse srcnew puis lui affecte l'infobulle titlenew.
  3. Ecrire une fonction Charge2Images(src1,title1,src2,title2) qui initialise un tableau multidimensionnel défini en variable globale et dont chaque cellule est un tableau associatif contenant l'adresse d'une image et son infobulle associée.
    La correction propose également une solution plus générale pour un nombre quelconque d'images. Vous pouvez essayer d'écrire une telle fonction si vous avez le temps...
  4. Ecrire une page XHTML contenant un formulaire dont le premier champ est une zone de texte permettant de saisir un nombre et le second est une sélection proposant les options "euros" et "francs". Lorsque le montant ou la monnaie est modifié, un autre champ de texte (non modifiable de préférence) doit prendre la valeur convertie et une image de la monnaie de conversion doit étre affichée.
  5. Ecrire une fonction qui, étant donné un préfixe de nom d'images, leur nombre et un tableau d'adresses d'images de taille quelconque, affecte aléatoirement à chacune des images nom+numero une des adresses du tableau.
    On ne se préoccupe pas des éventuels doublons.
    Ecrivez une page XHTML permettant de tester cette fonction.
  6. Ecrivez à l'aide d'un script une page XHTML contenant des étoiles (*) qui forment un triangle dont la hauteur est définie par une variable.
  7. A l'aide des scripts présentés en exemple sur cette page, ecrivez une fonction permettant d'ouvrir deux pages Internet dans deux nouvelles fenêtres ; les adresses des pages sont passées en paramètre.

Pour vérifier vos solutions et découvrir de petites subtilités, vous pouvez aller voir la correction.

 Liens et bibliographie