<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
  <head>
    <title>Openweb.eu.org - Introduction au langage ECMAScript</title>
    <meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
    <link rel="schema.DC" href="http://purl.org/dc/elements/1.1/" />
    <meta name="DC.Language" scheme="RFC3066" content="fr" />
    <meta name="DC.Identifier" content="introduction_ecmascript" />
    <meta name="DC.Creator" content="Florian Hatat" />
    <meta name="DC.Date.created" scheme="W3CDTF" content="2003-03-21" />
    <meta name="DC.Date.modified" scheme="W3CDTF" content="2003-03-21" />
    <meta name="DC.Rights" content="Cet article est sous licence Creative Commons Attribution-ShareAlike." />
    <meta name="DC.Subject" content="debutant, pages_dynamiques, dom" />
  </head>
  <body>
    <h1>Introduction au langage ECMAScript</h1>
    <ul>
      <li>
        <strong>Profil :</strong> <a href="/debutant/">Débutant</a>
      </li>
      <li>
        <strong>Thème :</strong> <a href="/pages_dynamiques/">Pages dynamiques</a>
      </li>
      <li>
        <strong>Technologie :</strong> <a href="/dom/">DOM</a>
      </li>
      <li>
        <strong>Auteur :</strong> <a href="mailto:florian.hatat%40openweb.eu.org">Florian Hatat</a>
      </li>
      <li>
        <strong>Mise à jour :</strong> 21/03/2003</li>
    </ul>
    <h2>En bref</h2>
    <p> JavaScript est un langage de programmation utilisé principalement sur le Web, développé par Netscape et repris par Microsoft sous le nom de JScript. ECMAScript est une tentative de normalisation du noyau du langage : sa syntaxe, ses mots-clés et ses composants natifs.</p>
    <hr />
    <p>JavaScript est un langage de programmation utilisé principalement sur le Web, développé par Netscape et repris par Microsoft sous le nom de JScript. ECMAScript est une tentative de normalisation du noyau du langage : sa syntaxe, ses mots-clés et ses composants natifs. La troisième édition du standard <acronym title="European Computer Manufacturer Association" lang="en">ECMA</acronym>-262 a été publiée en décembre 1999.</p>
    <h3>Les commentaires</h3>
    <p>Avant d'aborder la syntaxe du langage, voyons où nous pourrons l'enfreindre à loisir… Les commentaires vous permettent en effet de loger votre prose presque n'importe où dans un script, sans en modifier le comportement lors de l'exécution. Il existe deux types de commentaires en ECMAScript ;
dans le premier cas, le commentaire commence par les caractères <code>//</code> et se termine à la fin de la ligne ; dans le second, il débute avec les caractères <code>/*</code>, peut se prolonger sur plusieurs lignes et s'achève dès que les caractères <code>*/</code> sont rencontrés par l'interpréteur.</p>
    <pre>
// Un premier commentaire sur une ligne
/* Un deuxième commentaire */
/* Un troisième commentaire
sur plusieurs lignes */
    </pre>
    <p>Les commentaires ne s'imbriquent pas l'un dans l'autre ; les exemples suivants provoquent une erreur de syntaxe :</p>
    <pre>
/* ce texte est compté /* dans le commentaire */ mais pas celui-ci */
/* dans // le commentaire */ hors du commentaire
    </pre>
    <h3>Les variables</h3>
    <p>Une variable est un emplacement réservé en mémoire, désigné par un nom particulier, qui permet de stocker puis de réutiliser des données. Une variable est créée avec le mot-clé <code>var</code> suivi du nom qui doit lui être donné et d'un point-virgule, qui termine toute instruction ECMAScript.</p>
    <pre>var réponse;</pre>
    <p>Vous pouvez donner n'importe quel nom à vos variables, tant que ce dernier respecte certaines règles : il doit commencer par une lettre ou par les caractères <code>$</code> ou <code>_</code>, et peut se poursuivre avec des chiffres, mais pas avec des espaces ni des sauts de lignes. Il doit également être unique, c'est-à-dire que deux variables différentes ne peuvent pas porter le même nom, et il est sensible à la casse des caractères. De plus vous ne pouvez utiliser ni les mots-clés, que nous verrons par la suite, ni les mots réservés pour nommer vos variables.</p>
    <p>Mots réservés par ECMAScript :</p>
    <ul>
      <li>
        <code>abstract</code> ;</li>
      <li>
        <code>boolean</code> ;</li>
      <li>
        <code>byte</code> ;</li>
      <li>
        <code>char</code> ;</li>
      <li>
        <code>class</code> ;</li>
      <li>
        <code>const</code> ;</li>
      <li>
        <code>debugger</code> ;</li>
      <li>
        <code>double</code> ;</li>
      <li>
        <code>enum</code> ;</li>
      <li>
        <code>export</code> ;</li>
      <li>
        <code>extends</code> ;</li>
      <li>
        <code>final</code> ;</li>
      <li>
        <code>float</code> ;</li>
      <li>
        <code>goto</code> ;</li>
      <li>
        <code>implements</code> ;</li>
      <li>
        <code>import</code> ;</li>
      <li>
        <code>int</code> ;</li>
      <li>
        <code>interface</code> ;</li>
      <li>
        <code>long</code> ;</li>
      <li>
        <code>native</code> ;</li>
      <li>
        <code>package</code> ;</li>
      <li>
        <code>private</code> ;</li>
      <li>
        <code>protected</code> ;</li>
      <li>
        <code>public</code> ;</li>
      <li>
        <code>short</code> ;</li>
      <li>
        <code>static</code> ;</li>
      <li>
        <code>super</code> ;</li>
      <li>
        <code>synchronized</code>
      </li>
      <li>
        <code>throws</code> ;</li>
      <li>
        <code>transient</code> ;</li>
      <li>
        <code>volatile</code>.</li>
    </ul>
    <p>Il existe cinq types de données primitifs en ECMAScript. Les deux premiers sont quelque peu différents des autres : ce sont les types <code>Undefined</code> et <code>Null</code> qui n'admettent d'une seule valeur, respectivement <code>undefined</code> et <code>null</code>. Toute variable qui n'a pas encore reçu de valeur spécifique vaut <code>undefined</code> alors que la valeur <code>null</code> peut, selon le contexte, représenter une variable explicitement vide ou une fonction non gérée. Les trois autres types de données, <code>Boolean</code>, <code>Number</code> et <code>String</code>, admettent en revanche plusieurs valeurs différentes. Le type <code>Boolean</code>, qui représente les nombres booléens, accepte en effet exactement deux valeurs qui s'excluent mutuellement : <code>true</code> (vrai) et <code>false</code> (faux).</p>
    <pre>
var bonne_réponse;
bonne_réponse = true; /* Un booléen */
    </pre>
    <p>Notez que vous pouvez rejoindre les deux instructions en une seule autre équivalente :</p>
    <pre>var bonne_réponse = true;</pre>
    <p>Le type <code>Number</code> permet de manipuler les nombres à virgule flottante, en valeur approchée, comme décrits dans la norme IEEE 754-1985. Le point ici agit en séparateur des parties entière et décimale. Ce type possède quelques valeurs notables, comme <code>Infinity</code> pour l'infini positif, <code>NaN</code> pour désigner ce qui n'est pas un nombre (le résultat d'une division par zéro par exemple), ou un zéro négatif, que l'on saura utiliser si nécessaire et ignorer dans les autres cas.</p>
    <pre>
var taux_tva = 0.196;
var superficie_de_la_terre = 134.288e6; // 134 288 000 km²
/* Le 'e6' (exposant 6) signifie "10 puissance 6" et ne s'emploie
que dans ce cas précis, où il définit un nombre */
var députés = 0x241; /* Le nombre de députés à l'Assemblée Nationale, en
hexadécimal comme l'indique le préfixe '0x' */
var univers = Infinity; /* L'univers est infini, tout le monde le sait :-) */
var zéro_négatif = -0; /* Oui, un zéro négatif, distinct de +0 */
    </pre>
    <p>Enfin le type <code>String</code> permet d'utiliser des chaînes de caractères, dont la longueur n'est, a priori, pas limitée.</p>
    <pre>var question = "Quelle est la Réponse ?"</pre>
    <p>Dans l'exemple précédent, nous avons créé une chaîne de caractères qui contient le texte Quelle est la Réponse ? ; les guillemets servent uniquement à délimiter la chaîne et n'en font pas partie. Cependant certains caractères ne peuvent pas apparaître tels quels quand vous créez la chaîne : il s'agit notamment des sauts de ligne et des guillemets eux-mêmes. Vous devez alors utiliser une séquence d'échappement : c'est un groupe de caractères automatiquement remplacé par le caractère, unique, qu'il symbolise. Les guillemets sont échappés avec la séquence <code>\"</code> et le saut de ligne avec <code>\n</code>.</p>
    <pre>var dialogue = "Il a dit : \"…\"\nJ'ai répondu : \"…\"";</pre>
    <p>La variable <code>dialogue</code> contient le texte suivant :</p>
    <pre>
Il a dit : "…"
J'ai répondu : "…"
    </pre>
    <p>Cet exemple pourrait cependant être simplifié en utilisant des apostrophes (ou guillements simples) à la place des guillements doubles pour délimiter la chaîne, le résultat étant totalement identique. Cette solution a le mérite d'être plus lisible mais vous ne pouvez plus insérer d'apostrophes dans le texte sans les échapper.</p>
    <pre>var dialogue = 'Il a dit : "…"\nJ\'ai répondu : "…"';</pre>
    <p>Il existe quelques autres séquences d'échappement simples, c'est-à-dire ne comportant qu'un seul caractère après <code>\</code>, mais ECMAScript permet surtout d'insérer n'importe quel caractère de l'Unicode dans une chaîne en l'échappant sous la forme <code>\uXXXX</code> où <code>XXXX</code> est son code hexadécimal dans la table Unicode.</p>
    <pre>var ego = "\u0046\u006c\u006f\u0072\u0069\u0061\u006e";</pre>
    <p>Voici un moyen particulièrement pervers pour simplement écrire mon prénom… Le tableau suivant présente les séquences d'échappement simples définies par le standard ECMA-262.</p>
    <table width="100%" border="1" rules="all">
      <caption>Séquences d'échappement ECMAScript</caption>
      <thead>
        <tr>
          <th>Séquence d'échappement</th>
          <th>Séquence Unicode</th>
          <th>Nom</th>
          <th>Symbole</th>
          <th>Échappement obligatoire ?</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>
            <code>\b</code>
          </td>
          <td>
            <code>\u0008</code>
          </td>
          <td>backspace</td>
          <td>&lt;BS&gt;</td>
          <td>Non</td>
        </tr>
        <tr>
          <td>
            <code>\t</code>
          </td>
          <td>
            <code>\u0009</code>
          </td>
          <td>tabulation horizontale</td>
          <td>&lt;HT&gt;</td>
          <td>Non</td>
        </tr>
        <tr>
          <td>
            <code>\n</code>
          </td>
          <td>
            <code>\u000A</code>
          </td>
          <td>fin de ligne</td>
          <td>&lt;LF&gt;</td>
          <td>Oui</td>
        </tr>
        <tr>
          <td>
            <code>\v</code>
          </td>
          <td>
            <code>\u000B</code>
          </td>
          <td>tabulation verticale</td>
          <td>&lt;VT&gt;</td>
          <td>Non</td>
        </tr>
        <tr>
          <td>
            <code>\f</code>
          </td>
          <td>
            <code>\u000C</code>
          </td>
          <td>envoi de formulaire</td>
          <td>&lt;FF&gt;</td>
          <td>Non</td>
        </tr>
        <tr>
          <td>
            <code>\r</code>
          </td>
          <td>
            <code>\u000D</code>
          </td>
          <td>retour charriot</td>
          <td>&lt;CR&gt;</td>
          <td>Oui</td>
        </tr>
        <tr>
          <td>
            <code>\"</code>
          </td>
          <td>
            <code>\u0022</code>
          </td>
          <td>guillemets</td>
          <td>"</td>
          <td>Parfois</td>
        </tr>
        <tr>
          <td>
            <code>\'</code>
          </td>
          <td>
            <code>\u0027</code>
          </td>
          <td>apostrophe</td>
          <td>'</td>
          <td>Parfois</td>
        </tr>
        <tr>
          <td>
            <code>\\</code>
          </td>
          <td>
            <code>\u005C</code>
          </td>
          <td>anti-slash</td>
          <td>\</td>
          <td>Oui</td>
        </tr>
      </tbody>
    </table>
    <p>Signalons enfin qu'ECMAScript est amené à réaliser automatiquement des conversions quand elles sont nécessaires, dans des situations où un booléen est attendu et qu'un nombre est donné par exemple. Les tableaux suivants, extraits de la section 9 du standard <acronym>ECMA</acronym>-262, présentent les règles utilisées pour de telles conversions.</p>
    <table width="100%" border="1" rules="all">
      <caption>Conversion vers le type <code>Boolean</code>
      </caption>
      <thead>
        <tr>
          <th>Type d'origine</th>
          <th>Résultat</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>
            <code>Undefined</code>
          </td>
          <td>
            <code>false</code>
          </td>
        </tr>
        <tr>
          <td>
            <code>Null</code>
          </td>
          <td>
            <code>false</code>
          </td>
        </tr>
        <tr>
          <td>
            <code>Boolean</code>
          </td>
          <td>Le résultat est identique à la valeur d'origine (pas de conversion).</td>
        </tr>
        <tr>
          <td>
            <code>Number</code>
          </td>
          <td>
              Le résultat vaut <code>false</code> si le nombre vaut <code>+0</code>, <code>-0</code> ou         <code>NaN</code> ; sinon il vaut <code>true</code>.
            </td>
        </tr>
        <tr>
          <td>
            <code>String</code>
          </td>
          <td>
              Le résultat est <code>false</code> si la chaîne est vide (de longueur nulle) ; sinon le résultat est <code>true</code>.
            </td>
        </tr>
      </tbody>
    </table>
    <table width="100%" border="1" rules="all">
      <caption>Conversion vers le type <code>Number</code>
      </caption>
      <thead>
        <tr>
          <th>Type d'origine</th>
          <th>Résultat</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>
            <code>Undefined</code>
          </td>
          <td>
            <code>NaN</code>
          </td>
        </tr>
        <tr>
          <td>
            <code>Null</code>
          </td>
          <td>
            <code>+0</code>
          </td>
        </tr>
        <tr>
          <td>
            <code>Boolean</code>
          </td>
          <td>
              Le résultat est <code>1</code> si le booléen vaut <code>true</code>, et <code>+0</code> si le booléen vaut <code>false</code>.
            </td>
        </tr>
        <tr>
          <td>
            <code>Number</code>
          </td>
          <td>Le résultat est identique à la valeur d'origine (pas de conversion).</td>
        </tr>
        <tr>
          <td>
            <code>String</code>
          </td>
          <td>Le langage tente d'interpréter la chaîne en suivant la syntaxe des nombres.</td>
        </tr>
      </tbody>
    </table>
    <table width="100%" border="1" rules="all">
      <caption>Conversion vers le type <code>String</code>
      </caption>
      <thead>
        <tr>
          <th>Type d'origine</th>
          <th>Résultat</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>
            <code>Undefined</code>
          </td>
          <td>
            <code>"undefined"</code>
          </td>
        </tr>
        <tr>
          <td>
            <code>Null</code>
          </td>
          <td>
            <code>"null"</code>
          </td>
        </tr>
        <tr>
          <td>
            <code>Boolean</code>
          </td>
          <td>
              Si le booléen vaut <code>true</code>, le résultat est <code>"true"</code>. Si le booléen vaut <code>false</code>, le résultat est <code>"false"</code>.
            </td>
        </tr>
        <tr>
          <td>
            <code>Number</code>
          </td>
          <td>
              L'interpréteur donne une réprésentation du nombre tel qu'il aurait pu être écrit dans le code source du programme.
            </td>
        </tr>
        <tr>
          <td>
            <code>String</code>
          </td>
          <td>Le résultat est identique à la valeur d'origine (pas de conversion).</td>
        </tr>
      </tbody>
    </table>
    <h3>Les expressions</h3>
    <p>L'expression est un point fondamental du langage : presque toute instruction en contient, au moins, une. Une expression est une suite d'opérateurs et de valeurs opérandes. On dit qu'elle est évaluée quand l'interpréteur effectue les différentes opérations, en respectant les priorités des opérateurs, un peu à la manière d'un calcul algébrique.</p>
    <pre>3 + 4 * 7 / 2 - 9</pre>
    <p>Pour évaluer l'expression précédente, l'interpréteur va d'abord regrouper chaque opérande avec son opérateur, ce qui peut être symbolisé par l'ajout de parenthèses :</p>
    <pre>(3 + ((4 * (7 / 2)) - 9))</pre>
    <p>Notez que seul 2 est compté comme diviseur et non 2-9, car la division a une priorité plus importante que la soustraction. L'interpréteur effectue ensuite les calculs en partant de la parenthèse la plus intérieure.</p>
    <pre>
(3 + ((4 * (7 / 2)) - 9)) // La division
(3 + ((4 * 3.5) - 9)) // La multiplication
(3 + (14 - 9))// La soustraction
(3 + 5) // L'addition
8
    </pre>
    <p>Quand toutes les opérations ont été effectuées, le résultat, ici 8, devient la valeur de l'expression tout entière. Ainsi les deux variables suivantes sont strictement égales :</p>
    <pre>
var i = 3 + 4 * 7 / 2 - 9;
var j = 8;
    </pre>
    <p>Bien sûr l'intérêt des expressions réside dans le fait de pouvoir utiliser des variables comme opérandes, et non dans ce type de calculs où toutes les valeurs sont fixées.</p>
    <h4>Opérateurs mathématiques</h4>
    <p>Avec l'exemple précédent nous avons vu quatre opérateurs mathématiques courants : ce sont des opérateurs binaires, c'est-à-dire qui acceptent deux opérandes. De plus leur opération s'effectue avec deux nombres et renvoie une valeur du type <code>Number</code>. Chaque opérateur possède également une certaine priorité qui peut se traduire par un entier : plus ce dernier est grand, plus la priorité de l'opération est élevée. Nous pouvons ainsi commencer à remplir notre tableau des opérateurs du langage ECMAScript.</p>
    <table width="100%" border="1" rules="all">
      <caption>Opérateurs mathématiques binaires</caption>
      <thead>
        <tr>
          <th>Opérateur</th>
          <th>Résultat</th>
          <th>Priorité</th>
          <th>Description</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>
            <code>Number</code> + <code>Number</code>
          </td>
          <td>
            <code>Number</code>
          </td>
          <td>12</td>
          <td>Addition de deux nombres</td>
        </tr>
        <tr>
          <td>
            <code>Number</code> - <code>Number</code>
          </td>
          <td>
            <code>Number</code>
          </td>
          <td>12</td>
          <td>Soustraction</td>
        </tr>
        <tr>
          <td>
            <code>Number</code> * <code>Number</code>
          </td>
          <td>
            <code>Number</code>
          </td>
          <td>13</td>
          <td>Multiplication</td>
        </tr>
        <tr>
          <td>
            <code>Number</code> / <code>Number</code>
          </td>
          <td>
            <code>Number</code>
          </td>
          <td>13</td>
          <td>Division</td>
        </tr>
        <tr>
          <td>
            <code>Number</code> % <code>Number</code>
          </td>
          <td>
            <code>Number</code>
          </td>
          <td>13</td>
          <td>Reste de la division euclidienne (modulo)</td>
        </tr>
      </tbody>
    </table>
    <p>Pour changer l'ordre d'évaluation des opérations, par exemple pour effectuer une addition avant une multiplication, utilisez simplement les parenthèses comme dans les exemples précédents pour regrouper les calculs concernés. Dans un de ces calculs, il peut arriver par exemple qu'un opérateur attende un nombre comme opérande, mais qu'il reçoive en fait un booléen ou une chaîne de caractères. Dans ce cas, la valeur est convertie en nombre en suivant les règles de conversion du paragraphe précédent.</p>
    <p>Parmi ces cinq opérateurs, il en existe un qui nécessite une attention particulière : c'est l'opérateur +, ou plutôt les opérateurs +, car il en a bien plusieurs. Le premier ne change pas, c'est toujours l'addition. Quant au second, c'est l'opérateur de concaténation de chaînes, qui met bout à bout deux chaînes de caractères. Tous deux sont binaires, mais l'opérateur de concaténation réclame qu'au moins un de ses arguments soit une valeur du type <code>String</code>. Si ce n'est pas le cas, alors c'est la simple addition qui est effectuée.</p>
    <pre>var i = "20" + 3;</pre>
    <p>Dans cet exemple, la variable <strong>i</strong> est une chaîne de caractères qui contient le texte <code>203</code>, et non le nombre <code>23</code>.</p>
    <p>Il ne nous reste plus que deux opérateurs mathématiques, unaires pour leur part. Ce sont les opérateurs de signe + et -, mais ils ne peuvent pas être confondus avec leurs homologues binaires, car ces derniers sont toujours précédés d'un opérande, ce qui n'est pas le cas des opérateurs de signe. L'opérateur - convertit son opérande en nombre et retourne l'opposé de ce nombre, tandis que l'opérateur + le convertit uniquement en nombre.</p>
    <table width="100%" border="1" rules="all">
      <caption>Les opérateurs de concaténation et de signes</caption>
      <thead>
        <tr>
          <th>Opérateur</th>
          <th>Résultat</th>
          <th>Priorité</th>
          <th>Description</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>
            <code>String</code> + <code>String</code>
          </td>
          <td>
            <code>String</code>
          </td>
          <td>13</td>
          <td>Concaténation de chaînes</td>
        </tr>
        <tr>
          <td>+ <code>Number</code>
          </td>
          <td>
            <code>Number</code>
          </td>
          <td>14</td>
          <td>Conversion en nombre</td>
        </tr>
        <tr>
          <td>- <code>Number</code>
          </td>
          <td>
            <code>Number</code>
          </td>
          <td>14</td>
          <td>Opposé du nombre</td>
        </tr>
      </tbody>
    </table>
    <h4>Opérateurs d'affectation</h4>
    <p>Nous avons utilisé à plusieurs reprises jusqu'ici le symbole « <code>=</code> » en lui donnant implicitement sa signification mathématique. Mais c'est en fait (en doutiez-vous ?) l'opérateur d'affectation simple, qui se contente de prendre, sans aucune conversion et quel que soit son type, la valeur qui le suit pour la stocker dans la variable qui le précède. Mais n'avais-je pas laissé entendre que les variables étaient remplacées par leur valeur ? Sûrement, mais c'était un mensonge… Les noms de variables sont en fait des valeurs d'un type particulier, interne à l'interpréteur, et que vous ne pourrez jamais manipuler directement dans vos scripts : c'est le type <code>Reference</code>. Un nom de variable est une référence, un lien
ou encore un pointeur (oui, même en ECMAScript), vers la valeur de la variable. Lorsqu'ils rencontrent une <code>Reference</code>, tous les opérateurs vont automatiquement chercher la valeur associée, tous sauf les opérateurs d'affectation. Voilà pourquoi vous ne pourrez jamais écrire <strong>3 = 2</strong>, car
<code>3</code> est du type <code>Number</code> et non <code>Reference</code>.</p>
    <p>L'opérateur « <code>=</code> » possède plusieurs dérivés comme l'opérateur « <code>+=</code> ». L'écriture <strong>a += b</strong> est strictement équivalente à <strong>a = a + b</strong>. Des opérateurs similaires existent pour les soustraction, multiplication, division et modulo.</p>
    <p>ECMAScript possède enfin les traditionnels opérateurs unaires d'incrémentation, « <code>++</code> » et de décrémentation « <code>--</code> ». L'opérateur « <code>++</code> » convertit son opérande en nombre et lui ajoute 1, alors que « <code>--</code> » lui enlève 1. Ces deux opérateurs renvoient l'ancienne valeur de la variable.</p>
    <pre>
var i = 8;
var j = i++; /* i vaut 9, j vaut 8 */
      </pre>
    <table width="100%" border="1" rules="all">
      <caption>Opérateurs d'affectation et d'incrémentation</caption>
      <thead>
        <tr>
          <th>Opérateur</th>
          <th>Résultat</th>
          <th>Priorité</th>
          <th>Description</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>
            <code>Reference</code> = <code>(valeur)</code>
          </td>
          <td>
            <code>(valeur)</code>
          </td>
          <td>2</td>
          <td>Affectation simple</td>
        </tr>
        <tr>
          <td>
            <code>Reference</code> += <code>Number</code>
          </td>
          <td>
            <code>Number</code>
          </td>
          <td>2</td>
          <td>Addition et affectation (similaire avec -=, *=, /= et %=)</td>
        </tr>
        <tr>
          <td>
            <code>Reference</code>++</td>
          <td>
            <code>Number</code>
          </td>
          <td>15</td>
          <td>Incrémentation</td>
        </tr>
        <tr>
          <td>
            <code>Reference</code>--</td>
          <td>
            <code>Number</code>
          </td>
          <td>15</td>
          <td>Décrémentation</td>
        </tr>
      </tbody>
    </table>
    <h4>Opérateurs relationnels</h4>
    <p>Les opérateurs relationnels sont des opérateurs qui servent à comparer deux nombres entre eux, pour déterminer les relations d'infériorité stricte avec « <code>&lt;</code> », d'infériorité large « <code>&lt;=</code> », de supériorité stricte « <code>&gt;</code> », ou de supériorité large « <code>&gt;=</code> ». Ces opérateurs binaires comparent deux nombres et renvoient un booléen : ce dernier vaut <code>true</code> si la relation exprimée est vérifiée, et <code>false</code> sinon. De plus il existe l'opérateur « <code>==</code> » (attention à bien doubler le signe) qui teste l'égalité de deux valeurs, après les avoir converties dans le même type. L'opérateur « <code>===</code> » teste également l'égalité, mais sans aucune conversion.</p>
    <pre>
12 == 12; /* Vrai */
false == 0; /* Vrai, avec une conversion */
false === 0; /* Faux avec cet opérateur */
null == undefined; /* Vrai, par convention */
null === undefined; /* Faux */
"12" == 12 /* Vrai */
12 == "12" /* Évidemment vrai */
12 === "12" /* Faux, dans tous les sens :-) */
      </pre>
    <p>Ces deux opérateurs possèdent chacun une négation : « <code>!=</code> » renvoie <code>true</code> quand « <code>==</code> » renvoyait <code>false</code> et inversement. Il en est de même avec « <code>!==</code> » et « <code>===</code> ».</p>
    <table width="100%" border="1" rules="all">
      <caption>Opérateurs relationnels</caption>
      <thead>
        <tr>
          <th>Opérateur</th>
          <th>Résultat</th>
          <th>Priorité</th>
          <th>Description</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>
            <code>Number</code> &gt; <code>Number</code>
          </td>
          <td>
            <code>Boolean</code>
          </td>
          <td>10</td>
          <td>Strictement supérieur</td>
        </tr>
        <tr>
          <td>
            <code>Number</code> &gt;= <code>Number</code>
          </td>
          <td>
            <code>Boolean</code>
          </td>
          <td>10</td>
          <td>Supérieur ou égal</td>
        </tr>
        <tr>
          <td>
            <code>Number</code> &lt; <code>Number</code>
          </td>
          <td>
            <code>Boolean</code>
          </td>
          <td>10</td>
          <td>Strictement inférieur</td>
        </tr>
        <tr>
          <td>
            <code>Number</code> &lt;= <code>Number</code>
          </td>
          <td>
            <code>Boolean</code>
          </td>
          <td>10</td>
          <td>Inférieur ou égal</td>
        </tr>
        <tr>
          <td>
            <code>(valeur)</code> == <code>(valeur)</code>
          </td>
          <td>
            <code>Boolean</code>
          </td>
          <td>9</td>
          <td>Égalité (large)</td>
        </tr>
        <tr>
          <td>
            <code>(valeur)</code> != <code>(valeur)</code>
          </td>
          <td>
            <code>Boolean</code>
          </td>
          <td>9</td>
          <td>Différence (large)</td>
        </tr>
        <tr>
          <td>
            <code>(valeur)</code> === <code>(valeur) </code>
          </td>
          <td>
            <code>Boolean</code>
          </td>
          <td>9</td>
          <td>Égalité (stricte)</td>
        </tr>
        <tr>
          <td>
            <code>(valeur)</code> !== <code>(valeur)</code>
          </td>
          <td>
            <code>Boolean</code>
          </td>
          <td>9</td>
          <td>Différence (stricte)</td>
        </tr>
      </tbody>
    </table>
    <h4>Opérateurs logiques</h4>
    <p>Les opérateurs logiques sont exclusivement réservés aux opérations entre booléens. Le premier d'entre eux  l'opérateur, unaire, de négation « <code>!</code> », qui renvoie <code>true</code> quand son opérande vaut <code>false</code> et inversement. Quant aux deux autres opérateurs, ils sont binaires et correspondent aux deux fonctions courantes « ET » et « OU ». Le « ET logique » est symbolisé par « <code>&amp;&amp;</code> », alors que le « OU logique » s'écrit « <code>||</code> ». Leurs comportements sont définis par les trois tableaux suivants.</p>
    <table width="100%" border="1" rules="all">
      <caption>ET logique</caption>
      <thead>
        <tr>
          <th>Opérande 1</th>
          <th>Opérande 2</th>
          <th>Résultat</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>
            <code>false</code>
          </td>
          <td>
            <code>false</code>
          </td>
          <td>
            <code>false</code>
          </td>
        </tr>
        <tr>
          <td>
            <code>true</code>
          </td>
          <td>
            <code>false</code>
          </td>
          <td>
            <code>false</code>
          </td>
        </tr>
        <tr>
          <td>
            <code>false</code>
          </td>
          <td>
            <code>true</code>
          </td>
          <td>
            <code>false</code>
          </td>
        </tr>
        <tr>
          <td>
            <code>true</code>
          </td>
          <td>
            <code>true</code>
          </td>
          <td>
            <code>true</code>
          </td>
        </tr>
      </tbody>
    </table>
    <table width="100%" border="1" rules="all">
      <caption>OU logique</caption>
      <thead>
        <tr>
          <th>Opérande 1</th>
          <th>Opérande 2</th>
          <th>Résultat</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>
            <code>false</code>
          </td>
          <td>
            <code>false</code>
          </td>
          <td>
            <code>false</code>
          </td>
        </tr>
        <tr>
          <td>
            <code>true</code>
          </td>
          <td>
            <code>false</code>
          </td>
          <td>
            <code>true</code>
          </td>
        </tr>
        <tr>
          <td>
            <code>false</code>
          </td>
          <td>
            <code>true</code>
          </td>
          <td>
            <code>true</code>
          </td>
        </tr>
        <tr>
          <td>
            <code>true</code>
          </td>
          <td>
            <code>true</code>
          </td>
          <td>
            <code>true</code>
          </td>
        </tr>
      </tbody>
    </table>
    <table width="100%" border="1" rules="all">
      <caption>Utilisation des opérateurs logiques</caption>
      <thead>
        <tr>
          <th>Opérateur</th>
          <th>Résultat</th>
          <th>Priorité</th>
          <th>Description</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>!<code>Boolean</code>
          </td>
          <td>
            <code>Boolean</code>
          </td>
          <td>14</td>
          <td>Négation logique</td>
        </tr>
        <tr>
          <td>
            <code>Boolean</code> &amp;&amp; <code>Boolean</code>
          </td>
          <td>
            <code>Boolean</code>
          </td>
          <td>5</td>
          <td>ET logique</td>
        </tr>
        <tr>
          <td>
            <code>Boolean</code> || <code>Boolean</code>
          </td>
          <td>
            <code>Boolean</code>
          </td>
          <td>4</td>
          <td>OU logique</td>
        </tr>
      </tbody>
    </table>
    <h3>Contrôle de flux</h3>
    <p>Tout programme un peu évolué doit tôt ou tard prendre des décisions selon la valeur de certaines variables et savoir adapter son comportement. De même il doit avoir la capacité de répéter certaines actions ou d'interrompre son déroulement normal quand une erreur se produit : toutes ces fonctions sont gérées par des structures de contrôle de flux.</p>
    <h4>Savoir décider</h4>
    <p>Il existe deux structures dédiées à la prise de décision :<code>if</code> et <code>switch</code>. La structure <code>if</code> suit le schéma si-alors-sinon et s'utilise de la façon suivante :</p>
    <pre>
if ( …expression à tester… )
{
  instructions si vrai
}
else {
  instructions si faux
}
      </pre>
    <p>L'expression entre parenthèses est d'abord évaluée, et son résultat est converti en booléen. S'il vaut <code>true</code>, le premier bloc d'instructions est exécuté et le second ignoré ; s'il vaut <code>false</code>, seul le second est exécuté. La structure peut cependant être réduite en enlevant le mot-clé <code>else</code> et le bloc qui le suit, s'il n'y a rien à faire quand la condition est fausse. Les accolades définissent un bloc d'instructions, qui est obligatoire avec toutes les structures de contrôle dès qu'il y a plus d'une instruction à exécuter. Pour résumer : une seule instruction, les accolades sont facultatives ; plusieurs instructions, les accolades sont obligatoires.</p>
    <p>La structure <code>if</code> ne permet de tester que deux possibilités, cependant il est possible d'imbriquer plusieurs <code>if</code> l'un dans l'autre pour effectuer des tests plus complets.</p>
    <pre>
if (un_nombre == 1)
{
  // un_nombre vaut 1, faire quelque chose
}
else{
  if (un_nombre == 2){
    // un_nombre vaut 2, faire autre chose
  }
  else{
    // un_nombre ne vaut ni 1, ni 2, que faire ?
  }
}
      </pre>
    <p>Si cela fonctionne, il est pourtant déconseillé d'utiliser ainsi <code>if</code>, car la structure <code>switch</code> est plus adaptée à ce genre de tests. <code>switch</code> ne réagit pas selon la vérité logique d'une expression mais selon les différentes valeurs que cette dernière peut retourner. Voici comment elle s'utilise avec un exemple.</p>
    <pre>
switch ( un_nombre )// Une expression quelconque
{ /* L'accolade, toujours obligatoire ici,
  il ne s'agit pas d'un bloc d'instructions */
  case 1: /* un_nombre vaut 1 */
    // des instructions sans accolades
    break;/* Le mot-clé break pour sortir de la structure */
  case 2:
  case 3:
    /* On exécute les mêmes instructions pour les valeurs 2 et 3
    car il n'y a pas eu de "break;" */
    break;
  default:/* Que faire quand c'est un imprévu ? */
    // Des instructions
    break;
}
      </pre>
    <p>Une structure <code>switch</code> fonctionne d'après un principe de « branchements » : selon la valeur de l'expression dans l'en-tête, l'interpréteur ira au <code>case</code> correspondant et exécutera toutes les instructions qui suivent, tant qu'aucun <code>break</code> n'est rencontré. Ainsi dans l'exemple précédent, les mêmes instructions sont exécutées pour les valeurs <code>2</code> et <code>3</code> puisqu'il n'y a aucun <code>break</code> avant la ligne <code>case 3 :</code>. Le branchement <code>default</code> permet enfin d'intercepter toutes les valeurs, sauf celles pour lesquelles il existe déjà un branchement <code>case</code>.</p>
    <h4>Travailler à la chaîne</h4>
    <p>
        ECMAScript possède trois structures pour mettre en place un mécanisme de bouclage dans un script. La première, la structure <code>while</code>, s'utilise ainsi :</p>
    <pre>
while ( …expression à tester… )
{
  instructions à exécuter
}
      </pre>
    <p>Cette structure a un fonctionnement similaire à celui de <code>if</code> : l'interpréteur évalue l'expression entre parenthèses et exécute les instructions si cette dernière est vraie. A la fin du bloc d'instructions, l'expression est de nouveau testée et le bloc est de nouveau exécuté si elle est toujours vraie : pour éviter de créer une boucle infinie, il faut logiquement que l'expression à tester devienne fausse. L'exemple suivant donne un exemple d'une boucle infinie.</p>
    <pre>
while (true)
{
  /* Une boucle infinie qui ne fait rien, mais elle sera probablement
  rapidement rejetée par les navigateurs */
}
      </pre>
    <p>Si au premier passage dans la structure <code>while</code> la condition est fausse, le contenu de la boucle ne sera jamais exécuté : c'est ce qui la différencie de la structure <code>do while</code>. Avec cette structure, les instructions sont d'abord exécutées une première fois, puis la condition est testée pour savoir si l'on doit de nouveau exécuter le bloc.</p>
    <pre>
do
{
  instructions à exécuter
}
while ( …expression à tester… ); /* Attention au point-virgule ici */
      </pre>
    <p>La dernière structure, <code>for</code>, peut se concevoir comme un <code>while</code> évolué, et elle est particulièrement adaptée au cas où un certain nombre d'itérations doit être réalisé. Voici un exemple d'une
boucle <code>for</code> qui calcule la factorielle d'un nombre.</p>
    <pre>
var nombre, factorielle;
nombre = 9;
factorielle = 1; /* Ne surtout pas oublier, pour la multiplication qui suit */
for (var i = 1; i &lt;= nombre; i++)
{
  factorielle *= i;
}
</pre>
    <p>L'en-tête de la boucle se compose de trois parties séparées par des points-virgules. La première est évaluée une seule fois à l'entrée de la boucle ; ici elle initialise une variable <strong>i</strong> qui servira à l'intérieur. Puis la seconde partie est évaluée : c'est la condition dont dépend l'exécution du bloc. Si elle vaut <code>true</code>, le bloc est exécuté, sinon on sort de la boucle <code>for</code>. La troisième partie de l'en-tête est évaluée après chaque passage dans la boucle. Dans l'exemple précédent, nous exécutons neuf fois le bloc d'instructions, puis i atteint la valeur 10, ce qui rend fausse la deuxième expression. Nous aurions pu utiliser pour la même tâche une boucle <code>while</code>.</p>
    <pre>
var nombre, factorielle, i;
nombre = 9;
factorielle = i = 1;
while(i &lt;= nombre)
{
  factorielle *= i;
  i++;
}
      </pre>
    <p>Ou même une boucle <code>do while</code> qui fonctionne aussi pour le calcul de la factorielle :</p>
    <pre>
var nombre, factorielle, i;
nombre = 9;
factorielle = i = 1;
do
{
  factorielle *= i;
  i++;
}
while (i &lt;= nombre);
    </pre>
    <h3>Les fonctions</h3>
    <p>Le paragraphe précédent montrait comment calculer la factorielle d'un nombre. Pour calculer plusieurs factorielles différentes, vous pourriez recopier le petit morceau d'instructions, mais cette solution, triviale, possède au moins deux inconvénients immédiats : le code peut très vite devenir illisible et long, tandis que la modification de l'algorithme s'avère plus laborieuse. En programmeurs raisonnables, nous utiliserons donc une fonction ! C'est en effet un regroupement d'instructions, chargé d'accomplir une tâche spécifique et qui possède un nom. Ce dernier est utilisé par le reste du script pour exécuter la fonction autant de fois que nécessaire et il obéit aux mêmes règles de nommage que les variables. Pour créer une fonction, le mot-clé <code>function</code> s'utilise ainsi :</p>
    <pre>
function nom_de_la_fonction ()
{
  // instructions à exécuter
}
    </pre>
    <p>Quand l'interpréteur rencontre une telle déclaration, il n'exécute pas les instructions mais se souvient seulement qu'il existe une fonction qui possède tel nom à tel endroit du script, pour y revenir quand elle sera appelée. Après avoir déclaré votre fonction, vous pouvez l'exécuter simplement comme ceci :</p>
    <pre>nom_de_la_fonction();</pre>
    <p>Le corps de la fonction peut contenir n'importe quelle instruction. Cependant il existe un mot-clé particulier, <code>return</code>, qui termine immédiatement l'exécution de la fonction et définit sa valeur de retour. Une fonction renvoie en effet toujours une valeur au code qui l'a appelée : cette dernière remplace l'appel de la fonction, un peu à la manière d'une variable, et peut être utilisée comme opérande dans une expression. Le mot-clé <code>return</code> est habituellement suivi d'une expression : le résultat de son évaluation détermine la valeur de retour. Mais s'il est utilisé seul, il équivaut à <code>return undefined;</code>. Enfin, une fonction qui ne s'est pas terminée par <code>return</code> retourne toujours implicitement <code>undefined</code>.</p>
    <p>Dans de nombreuses situations, l'exécution d'une fonction requiert certaines valeurs qui vont l'influencer : une fonction factorielle doit par exemple connaître le nombre dont il faut justement calculer la factorielle. Ce rôle de passage de valeurs est assuré par les paramètres, qui s'ajoutent entre les parenthèses qui suivent le nom de la fonction. À sa déclaration, vous y mettez les noms des paramètres, pour les utiliser dans le corps de la fonction comme des variables, mais qui ne seront pas connues à l'extérieur.</p>
    <pre>
function ma_fonction(mon_param1, blabla, bouh, arg4)
{ /* etc., etc., etc. */ }
    </pre>
    <p>À l'appel de la fonction, les valeurs à donner à chaque paramètre prennent naturellement leur place entre les parenthèses, en suivant l'ordre de la déclaration.</p>
    <pre>ma_fonction(42, "un texte", true, null);</pre>
    <p>Lors de cette exécution de la fonction, <strong>mon_param1</strong> vaudra 42, <strong>blabla</strong> vaudra "un texte", etc. ECMAScript n'est pas très strict quant au passage des paramètres, c'est-à-dire que vous pouvez parfaitement passer moins de paramètres, ou au contraire plus qu'il n'en existe dans la déclaration. Les valeurs manquantes sont alors remplacées par <code>undefined</code>, tandis que les valeurs en trop sont ignorées (sauf si vous savez y accéder…).</p>
    <p>Ce petit tour d'horizon rapide des fonctions nous permet maintenant d'écrire notre fameuse fonction factorielle : elle utilisera un paramètre, normalement un entier positif, et renverra la factorielle de cet entier.</p>
    <pre>
function factorielle (nombre)
{
  var fact = 1;
  for (var i = 1; i &lt;= nombre; i++)
    fact *= i;
  return fact;
}
    </pre>
    <p>Ce n'est finalement pas très compliqué, ni robuste d'ailleurs, mais terriblement efficace à l'utilisation, car vous pouvez désormais calculer autant de factorielles qu'il vous plaîra.</p>
    <pre>
var factorielle_de_9 = factorielle(9);
factorielle(42); // Un grand nombre
factorielle(1e42); // Un nombre trop grand : on obtiendra +Infinity
    </pre>
    <p>Le dernier point de cette section concerne la récursivité, qui fait évidemment partie de tout langage qui se respecte un peu. Ce concept permet à une fonction de s'appeler elle-même pour effectuer une tâche récurrente, comme c'est parfaitement le cas de notre fonction factorielle.</p>
    <pre>
function factorielle (nombre)
{
  return nombre ? nombre * factorielle (nombre - 1) : 1;
}
    </pre>
    <p>Ce genre de fonction qui se mord la queue peut être très utile, voire indispensable dans certaines situations. Je vous laisser méditer l'exemple précédent, qui fonctionne tout aussi bien que l'ancienne fonction, avant de passer aux objets ECMAScript.</p>
    <h3>6. Pour conclure</h3>
    <p>Cet article a permis, je l'espère, d'acquérir quelques rudiments de la programmation avec ECMAScript. Il est cependant loin d'être exhaustif et plusieurs aspects du langage n'ont pas été évoqués. C'est par exemple le cas des objets, sur lesquels repose une grande partie du noyau <acronym>ECMA</acronym>-262. Finalement, seule la syntaxe de base trouve sa place ici. De plus ECMAScript ne peut pas se résumer qu'à son noyau, et pour créer des scripts vraiment utiles, il faudra utiliser d'autres technologies qui étendent le noyau, comme principalement le <acronym title="Document Object Model" lang="en">DOM</acronym>.</p>
    <h3>Bibliographie</h3>
    <p>[HTML401] <em>HTML 4.01 Specification</em>, 1999.</p>
    <p>[ECMA262] <em>ECMAScript Language Specification</em>, 1999.</p>
    <p>[MCFARLANE] McFarlane, Nigel. <em>JavaScript</em>, 1999.</p>
  </body>
</html>
