version 1.8.2, dernière mise à jour le 14 octobre 2024.
Pour commencer, tordons le cou à une erreur classique : JavaScript
et Java
ne sont en aucune manière apparentés. Il s'agit de deux langages différents. En effet, dans le cadre d'un site Web :
JavaScript
est le plus souvent interprété côté client, sur la machine sur laquelle tourne le navigateur qui analyse et affiche la page Web, alors que Java
peut être compilé ou interprété côté serveur.
Un code JavaScript
est appelé dans une page Web différemment d'une applet
Java
.
Il est nécessaire de déclarer les variables en Java
, alors que cette déclaration peut être implicite en JavaScript
.
JavaScript
a été mis au point par Brendan Eich de Netscape Communications et baptisé LiveScript 1.0
. Lorsque Java
de la compagnie Sun est devenu populaire, le langage a été rebaptisé JavaScript
.
La version 1.0 de JavaScript
a été intégrée par Netscape dans son navigateur Netscape Navigator 2.0
. Microsoft a alors suivi le mouvement et a introduit un langage compatible avec JavaScript
dans Internet Explorer 3.0
, le JScript 1.0
.
Netscape a sorti ensuite la version 1.1 de son langage, pendant que Microsoft sortait une version 1.1 de JScript
. Les deux langages étaient devenus en partie incompatibles.
Lorsque Netscape a rendu publiques les définitions de son langage afin de le rendre plus populaire, la compagnie et Microsoft ont trouvé un terrain d'entente afin de développer ECMAScript
, sous le patronage de l'ECMA, une organisation suisse, en juillet 1997. Cela n'empêcha pas les compagnies de publier en parallèle JavaScript 1.2
et JScript 2.0
qui étaient encore moins compatibles entre eux.
À cette époque, le quotidien du développeur Web consistait surtout à gérer les incompatibilités entre les navigateurs -incompatibilités dans le code de script utilisé, mais aussi dans les éléments HTML
supportés par chaque navigateur. Actuellement, les éditeurs de navigateur ont convergé sur le support de l'ECMAScript
, ce qui a permis le développement de nombreuses bibliothèques.
Il existe trois manières d'insérer du code JavaScript
dans un document (X)HTML :
La manière la plus simple à mettre en œuvre est l'utilisation des attributs prévus dans les recommandations (X)HTML pour cela : onclick
, onmouseover
, etc. Cette méthode présente un inconvénient majeur, celui de mêler le code destiné à donner la structure du document (le HTML
) au code destiné à interagir avec lui, le JavaScript
. La mise à jour d'une telle page est difficile, de la même manière que gérer la mise en forme CSS
à l'aide de l'attribut style
est une pratique généralement à déconseiller.
Une deuxième méthode, analogue à l'utlisation d'une feuille de style interne en CSS
, consiste à faire appel à l'élément script
et à insérer le code JavaScript
à l'intérieur de cet élément. Par exemple,
<script type="application/javascript">(…)</script>
L'attribut type
est obligatoire en HTML4
, facultatif en HTML5
. Vous rencontrerez parfois l'atttribut language
avec la valeur JavaScript
, mais cet attribut est obsolète et ne devrait donc plus être utilisé. La valeur type/javascript
est elle aussi obsolète depuis avril 2006 et a été remplacée par application/javascript
.
Cet élément peut être présent dans l'entête du fichier HTML
tout comme l'élément style
des feuilles de style internes. Il est aussi possible de l'insérer au cœur de la page HTML
, comme descendant de l'élément body
, mais cela complique encore une fois la maintenance de la page. Enfin, il peut être incorporé à la toute fin du code, avant la balise fermante </body>
. Cela a pour avantage de ne charger le code JavaScript qu'après le chargement de l'ensemble du HTML. Nous y reviendrons.
Une troisième méthode fait elle aussi appel à l'élément script
, mais cette fois-ci le code JavaScript
se trouve dans un fichier externe. Dans ce cas, l'élément script
précise à l'aide de l'attribut src
l'emplacement du fichier JavaScript
:
<script type="text/javascript" src="../scripts/aideSaisie.js">
Cette dernière méthode est la plus commode à mettre en œuvre si un script doit être utilisé sur plusieurs pages, mais elle doit être maniée avec précaution afin d'éviter toute perte d'informations. À la fin de ce cours, nous reviendrons sur de bonnes pratiques de codage à utiliser afin d'éliminer ce genre de soucis.
Par le passé, des outils de consultation de pages qui ne supportaient pas JavaScript
, ou, ce qui est pire, n'en avaient qu'un support partiel. De plus, les robos indexeurs des moteurs de recherche étaient incapables d'indexer du contenu produit en JavaScript
. C'est la raison pour laquelle, à chaque fois que du contenu ou une fonctionnalité était ajouté à une page en faisant appel à JavaScript
, il était nécessaire de prévoir une alternative sous un format accessible à ce genre d'outils de consultation (le plus souvent simplement du HTML
), et fournissant à ces outils une information équivalente et des fonctionnalités permettant d'atteindre les mêmes buts. Cette alternative devait être présente dans un élément noscript
, enfant de script
lorsqu'il est descendant de l'élément body. Par exemple :
<script>
(…)
<noscript>Information équivalente au contenu produit par le script</noscript>
</script>
À l'heure actuelle, ces limitations ne sont plus de mise, à moins que l'on ne se trouve face à un parc contraint de machines anciennes, ce qui peut arriver dans certaines structures. Officiellement, JavaScript
est en effet reconnu comme étant une technologie « compatible avec l'accessibilité », et à ce titre, il n'est plus nécessaire de prévoir une version « de secours ». En contrepartie, le code doit être conçu de sorte qu'il produise un contenu accessible et que son fonctionnement s'opère sans entraver l"utilisabilité de la page (par exemple, si une image est introduite par le JavaScript
, elle doit comporter une alternative textuelle pertinente ; si un menu déroulant est géré, il doit pouvoir être utilisé au clavier et à la souris, etc.).
JavaScript
est assez souple. Ainsi, écrire a = b + 2
ou a=b+2
est équivalent, et signifie que l'on affecte à la variable a
la valeur de la variable b
augmentée de 2. Il accepte de même l'insertion de tabulations au sein des expressions, avant ou après les opérateurs. On peut insérer un retour chariot partout où il est possible de placer un espace. Par conséquent, les lignes de code doivent se terminer par des ";
". Par exemple…
a
=
b
+
2
;
Un commentaire JavaScript
permet de placer du texte en-dehors du script : il n'est alors pas interprété. Deux syntaxes sont possibles :
Quand le commentaire s'étend sur une seule ligne, on peut commencer cette ligne par //
.
Quand le commentaire doit s'étendre sur plusieurs lignes, il doit commencer par /*
et se terminer par */
.
//Une ligne
/*Deux
lignes*/
JavaScript
est sensible à la casse employée. Par conséquent, variabletest
et Variabletest
désignent deux variables différentes.
Il existe un certain nombre de noms réservés, qui sont à peu près les mêmes que dans les autres langages de programmation, comme var
, function
, for
, if
… Nous les rencontrerons au fur et à mesure.
JavaScript
est un langage dans lequel il est possible de ne pas déclarer qu'une variable doit être d'un certain de type de données. Cela signifie qu'il suffit d'indiquer a=2;
, par exemple, pour déclarer premièrement que l'on définit une variable qui s'appelle a
et qui a pour valeur 2, mais aussi deuxièmement que cette variable est de type nombre.
Il n'existe que quelques types de données en JavaScript
, ce qui en facilite l'usage mais complique le contrôle des valeurs autorisées pour une variable donnée. Ces types prédéfinis sont :
la chaîne de caractères. Une chaîne de caractères est délimitée par des "
ou '
. Par exemple, a="Ceci est une chaîne" ;
. Si l'on doit utiliser des apostrophes ou des guillemets imbriqués, on peut faire appel à l'autre forme : "C'est une chaîne"
, voire « échapper » les caractères : 'Le duc déclara : "C\'est une affaire d\'honneur".'
Il existe d'autres caractères échappés : \b
correspond au retour arrière, \f
au saut de page, \n
au saut de ligne, \r
au retour chariot, \t
à la tabulation horizontale et finalement \\
au caractère \
lui-même.
Depuis ECMAScript 2015
, on peut plus facilement incorporer des valeurs de variables dans des chaînes de caractères. S'il reste possible d'écrire…
var chaine="Mon nom est " + prenom + " " + nom +".";
… on peut maintenant simplifier en…
var chaine=`Mon nom est ${prenom} ${nom}.`;
Attention au signe de ponctuation utilisé : il s'agit du caractère accent grave (AltGr+è
sur un clavier AZERTY). Il s'agit d'un « littéral de gabarit ».
les nombres. Il s'agit soit d'un nombre entier (par exemple 3, -456 ou 78900001), soit d'un nombre à virgule flottante (comme 3.1415 ou -745.6). Les nombres sont compris entre 224-1 et -(224), ce qui correspond à environ 10308. Certaines constantes correspondent à des valeurs particulières. Ce sont´:
positive Infinity
ou +Infinity
qui peut être obtenu quand on essaie d'ajouter une quantité strictement positive au plus grand nombre géré par le langage
negative Infinity
ou -Infinity
positive zero
ou +0
qui correspond à une valeur nulle positive
negative zero
ou -0
qui correspond à une valeur nulle négative
NaN
(Not A Number) qui est obtenu lorsque l'on essaie de réaliser une opération interdite (comme par exemple diviser par zéro)
les booléens, avec le type boolean
. Les variables de type booléen ne peuvent prendre que deux valeurs possibles : « vrai » (true
) ou « faux » (false)
.
les objets, avec le type object
. Il s'agit d'un moyen d'utiliser des objets en JavaScript
, qui est un langage orienté prototype.
undefined
est un type particulier, puisqu'il ne peut prendre qu'une seule valeur, undefined
. Lorsqu'une variable ne peut pas être définie ou ne l'a pas encore été, elle est de ce type.
null
est un dernier type possible. Il signifie qu'une variable ne contient pas de donnée.
JavaScript
permet de changer le type d'une variable, avec les fonctions suivantes :
parseInt()
et parseFloat()
permettent de convertir une chaîne de caractères en nombre (respectivement entier ou à virgule flottante). Si par exemple la variable x
contient la chaîne de caractères "34.7"
, parseInt(x)
renvoie 34, et parseFloat(x)
renvoie 34,7.
Number()
transforme un objet en nombre à la manière de parseFloat()
pour les chaînes de caractères.
string()
transforme un objet en chaîne de caractères.
Il est parfois nécessaire, avant de lancer un traitement sur des variables supposées être des nombres, de tester si tel est vraiment le cas.
L'opérateur typeof
renvoie une chaîne de caractères donnant le type d'une variable. Par exemple, typeof 42
renvoie comme résultat la chaîne de caractères "Number"
, mais typeof "42"
renvoie "string"
.
isFinite()
permet de tester si la variable passée en paramètre est bien un nombre fini (par exemple, isFinite(+Infinity)
renvoir le booléen false
).
isNaN()
teste si le paramètre n'est pas un nombre. Par exemple, isNaN(34.7)
renvoie false
, mais isNaN("abc")
renvoie true
.
Une déclaration (sans affectation de valeur) se fait à l'aide du mot-clef var
. Par exemple, var a;
déclare l'existence d'une variable s'appelant le nom a
, mais sans lui avoir affecté de valeur. Elle est donc de type undefined
.
On affecte une valeur à l'aide de l'opérateur =
. Par exemple, a="Ceci est une chaîne"
. Cet opérateur permet aussi d'affecter la même valeur à plusieurs variables. Par exemple, a=b=c=d=e=5;
affecte la valeur 5 aux cinq variables a
, b
, c
, d
et e
.
Ces opérateurs permettent d'effectuer une opération sur une variable puis de lui affecter le résultat.
+=
permet de réaliser une addition : si a
vaut 5, a+=2;
affecte 5+2=7 à a
.
-=
permet de réaliser une soustraction : si a
vaut 5, a-=2;
affecte 5-2=3 à a
.
*=
permet de réaliser une multiplication : si a
vaut 5, a*=2;
affecte 5*2=10 à a
.
/=
permet de réaliser une division : si a
vaut 5, a/=2;
affecte 5/2=2.5 à a
.
Cet opérateur permet d'affecter une valeur à une variable en fonction du résultat à un test. Sa syntaxe est la suivante :
variable=TestÀRéaliser ?valeurSiTestVrai:ValeurSiTestFaux
Par exemple, a=b>3?0:1
affecte 0 à a
si b
est strictement supérieur à 3, et 1 dans le cas contraire. Cette syntaxe permet aussi d'affecter une valeur à une variable si elle n'a pas été définie, tout en la laissant inchangée si elle l'a été, en écrivant par exemple a=a?a:"Valeur par défaut";
.
Variante de cette opérateur, et permettant aussi d'affecter une valeur par défaut si une variable n'est pas définie, l'opérateur de coalescence des nuls
??=
. Ainsi, on peut écrire a??=1
: si a ne vaut ni undefined
, ni null
, sa valeur ne sera pas changée ; dans le cas contraire, on lui affecte 1.
Parfois, il est nécessaire de répéter de mêmes portions de codes. Par exemple, on peut souhaiter afficher un résultat donné sous une certaine forme, ou bien faire un calcul répétitif. Dans ce cas, au lieu de réécrire plusieurs fois cette même portion de code, on définit ce que l’on appelle des fonctions. Ces fonctions peuvent accepter des paramètres, ou arguments, pour leur permettre de réaliser l’action désirée.
Une fonction est un ensemble d'instructions que l'on peut appeler séparément. La forme générale de sa déclaration est
function nomFonction(liste éventuelle des arguments)
{
(…)
}
Une fonction est ensuite appelée dans le code JavaScript
par nomFonction(arguments…)
. Une fonction peut ne pas nécessiter d'arguments (qui en sont les données d'entrée), et elle peut ne pas retourner de valeur en sortie.
Exemple de fonction ne prenant pas d’argument…
function quandSommesNous()
{
aujourdhui = new Date ;
alert(aujourdhui);
}
Une fonction peut éventuellement « retourner » une valeur à l'aide de l’instruction return
. Par exemple,
function surfaceRectangle(longueur, largeur)
{
return longueur*largeur ;
}
Un appel à cette fonction se fait par exemple ainsi :
alert(surfaceRectangle(2.5, 3))
À l'écran, une boîte d'affichage montrera 7.5.
La version 2015 d'ECMAScript
(dite aussi ES6) introduit la possibilité de définir des valeurs par défaut pour les paramètres passés à une fonction. On écrira ainsi, par exemple…
function surfaceRectangle(longueur=30, largeur=20)
{
return longueur*largeur ;
}
La portée d'une variable désigne l'ensemble du code dans lequel elle peut être utilisée. Elle peut être définie avec les mots-clefs var
, const
ou let
.
Si une variable est déclarée sans le mot-clef var
, elle peut être utilisée n'importe où dans le script. On l’appelle alors variable globale.
Si une variable est déclarée avec le mot-clef var
, elle ne peut être utilisée que dans la fonction où elle se trouve. On l’appelle alors variable locale. Ainsi, dans l'exemple suivant…
var a = 8 ;
function
testFonction()
{
var pi = 3.14 ;
(…) ;
}
function
testFonction2()
{
(…) ;
}
… la variable a
peut être utilisée dans les fonctions testFonction1
et testFonction2
, mais la variable pi
ne peut être utilisée que dans la fonction testFonction1
.
Cette possibilité de contrôler la portée d'une variable conduit à conseiller l'utilisation du mot-clef var
dès que cela est possible. Cela permet par exemple d'éviter d'écraser par inadvertance la valeur d'une variable portant le même nom.
Attention, ce mot-clef ne peut pas être « factorisé ». Si on écrit par exemple var a = b = c = 5;
, cela équivaut à var a=5; b=5; c=5;
: dans ce cas, seule la variable a
a une portée locale, b
et c
sont globales.
On peut affiner la portée d'une variable avec le mot-clef let
. let
permet de limiter la portée d'une variable à un bloc (compris entre deux accolades), alors que var
s'étend au-delà du bloc. Par exemple…
function testVarLet()
{
var x=5 ;
let y=5 ;
{
var x=6 ;
let y=6 ;
}
console.log(x) ;
console.log(y) ;
}
… renverra 6 puis 5, la portée de y
modifiée étant restée confinée dans le bloc.
const
fonctionne, du point de vue de la portée, de manière similaire à let
mais introduit une nuance de taille : on ne peut pas affecter une nouvelle valeur à une variable définie avec const
. Par exemple…
function testVarLet()
{
const X=5 ;
const X=6 ;
const Y={prop1:1, prop2:"essai"} ;
const Y={prop1:2, prop2:"test"} ;
}
… déclenchera des erreurs. Mais const
ne signifie pas que la « constante » ne peut pas changer ; cette instruction signifie que la variable (ici X
ou Y
) pointe toujours vers la même référence. Le code suivant ne produit ainsi pas d'erreur, car on ne change pas la valeur de la constante (qui continue à pointer vers un objet donné), mais son contenu :
function testVarLet()
{
const Z={prop1:1, prop2:"essai"} ;
const Z.prop1=2; Z.prop2="test" ;
}
Quelle que soit la fonction, déclarée avec des paramètres ou non, il est possible de récupérer la liste des arguments qui lui sont passés à l'aide de la propriété arguments
. Par exemple…
var moyenne = function(){
let somme = 0 ;
for (let i=0;i<arguments.length;i++) somme+=Number(arguments[i]) ;
console.log (somme/arguments.length) ;
}
Ainsi, moyenne(5)
renvoie 5, moyenne(1, 23, -4.3)
renvoie 6.566666666666666.
Ces fonctions ont été introduites avec ES6, et permettent d'alléger le code quand les instructions ne nécessitent pas beaucoup de traitement. Elles sont anonymes et sont destinées à faciliter l'appel aux callbacks (c'est-à-dire des fonctions passées en paramètres d'autres fonctions), même si on peut les affecter à une variable. Ces fonctions renvoivent toujours un résultat, mais le return
est implicite. La syntaxe générale est la suivante :
([param] [, param]) =>{
//instructions
}
La syntaxe la plus courte est par exemple var maFonction = x => x+2;
. On peut dès lors appeler la fonction classiquement, sous la forme maFonction(5.3)
.
Une fonction ne prenant pas de paramètre se déclare en explicitant des parenthèses : var maFonction = () => prompt("Saisissez une chaîne");
.
Le passage de plusieurs paramètres se fait, comme pour les fonctions plus « traditionnelles » en les listant entre parenthèses : var produitScalaire = (x, y) => (x[0]*y[0]+x[1]*y[1]);
Une fonction traditionnelle, avec des paramètres, possède toujours un tableau au nom prédéfini, arguments
, qui donne accès à tous les arguments avec lesquels la fonction a été appelée. Une fonction fléchée ne dispose pas de cette fonctionnalité.
Cela est dû à une notion que nous aborderons plus tard en détails : le contexte de la fonction, qui définit à quoi fait référence le mot-clef this
. Dans le cas d'une fonction tradionnelle, this
peut désigner plusieurs choses, en fonction de la manière dont une fonction est déclarée et utilisée. Une fonction fléchée ne crée pas de nouveau contexte, elle utilise la valeur this
de leur contexte.
Un tableau permet de déclarer une variable qui doit se présenter comme une collection de valeurs. On numérote alors ces valeurs à partir de 0. Par exemple,
//Déclaration d'un tableau de 4 éléments :
var tableau1 = new Array(4) ;
//Déclaration d'un tableau dont le nombre d'éléments est a priori inconnu :
var tableau2 = new Array() ;
Pour affecter des valeurs à un tableau, plusieurs possibilités sont disponibles :
On peut affecter les valeurs l'une après l'autre :
var tableau1 = new Array(4) ;
tableau1[0]="Beurre" ;
tableau1[1]="Confiture" ;
tableau1[2]="Pain" ;
tableau1[3]="Jus de fruit" ;
On peut affecter les valeurs en une seule ligne :
var tableau1 = new Array(4) ;
tableau1=["Beurre", "Confiture", "Pain", "Jus de fruit"] ;
Il est enfin possible de déclarer et définir le tableau simultanément :
var tableau1 = new Array('Beurre', 'Confiture', 'Pain', 'Jus de fruit') ;
La propriété length
d'un tableau renvoie son nombre d'éléments. Par exemple…
var tableau1 = new Array('Beurre', 'Confiture', 'Pain', 'Jus de fruit') ;
alert(tableau1.length) ;
… renvoie 4.
Un tableau à deux dimensions se déclare en déclarant tout d'abord un tableau à une dimension, puis en déclarant que chacun des éléments de ce tableau est lui-même un tableau. Par exemple,
var tableau1 = new Array(4) ;
for (i=0;i<tableau1.length;i++)
{
tableau1[i] = newArray(2) ;
}
La déclaration précédente amène à un tableau de 4×2 éléments. Le processus peut aisément être étendu à la déclaration d’un tableau quelconque de n dimensions.
indexOf(valeur)
et lastIndexOf(valeur)
renvoient respectivement l'indice du premier et du dernier élément d'un tableau valant valeur
findIndex
est une méthode renvoyant l'indice du premier élément du tableau correspondant au test réalisé par une fonction appliquée à cet élément. Si aucun élément du tableau ne passe le test, la méthode renvoie -1. find
en renvoie la valeur. Par exemple :
const tab = [1,2,3,6,10] ;
const test = x => x>5 ;
tab.findIndex(test) ;//renvoie 3
tab.find(test) //renvoie 6
Notez que pour cet exemple, on aurait tout aussi bien pu écrire tab.find(x => x>5)
.
every
est une méthode prenant comme argument une fonction renvoyant le résultat d'un test. Cette méthode renvoie true
si tous les éléments du tableau passent le test, false
sinon. Par exemple…
const tab = [1,2,3,6,10] ;
tab.every(x => x>0) //renvoie true
tab.every(x => x>5) //renvoie false
On peut ajouter des éléments à la fin d'un tableau, avec la méthode push()
: par exemple, var tableau1 = new Array (3);tableau1.push(23);
ajoute un quatrième élément au tableau, et tab[3]
vaut 23.
On peut ajouter des éléments au début d'un tableau, avec la méthode unshift()
: par exemple, var tableau1 = new Array (3);tableau1.unshift(23);
ajoute 23 comme premier élément au tableau et décale les autres éléments : tab[0]
vaut 23 et tab.length
renvoie 4.
On peut supprimer le premier élément d'un tableau avec la méthode shift()
, et le dernier élément du tableau avec la méthode pop()
. Cette méthode renvoie cet élément supprimé.
reverse
inverse l'ordre du tableau.
fill(valeur, [indexDébut], [indexFin])
, qui prend un, deux ou trois arguments, permet de remplir un tableau avec valeur
entre l'élément d'indice indexDébut
et l'élément d'indice indexFin
. Si indexFin
n'est pas précisé, le tableau est rempli jusqu'à la fin. Si de plus indexDébut
n'est pas précisé, alors toutes les valeurs du tableau sont remplacées par valeur
.
sort
trie le tableau. Le tri est réalisé en convertissant d'abord les éléments du tableau en chaînes de caractères, puis en triant par ordre croissant des codes UTF-16. Si on veut trier selon un autre ordre, il fait spécifier une fonction de comparaison. Cette fonction prend deux arguments x1
et x2
, et doit renvoyer 0 si on ne veut pas changer l'ordre entre x1
et x2
, un nombre négatif si on veut que x1
soit trié avant x2
, et un nombre positif si on veut que x1
soit classé après x2
. Par exemple, on peut trier un tableau de nombres en faisant…
const tab = [1,3,2,10,6] ;
tab.sort(function(x1,x2) {return x1-x2;}) //renvoie [1,2,3,6,10]
On peut là encore utiliser une fonction fléchée pour plus de lisibilité : tab.sort((x1,x2) => x1-x2)
Enfin, map
permet de modifier les valeurs du tableau sans avoir à faire de boucle. Par exemple :
const tab = [1,2,3,6,10] ;
tab.map(x => x*2) //renvoie [2,4,6,12,20]
Les opérateurs binaires sont ceux qui effectuent une opération sur deux variables ou données. Ces opérateurs sont :
+
permet dans le cas de deux nombres leur addition, et dans le cas de deux chaînes de caractères leur concaténation. Par exemple, 2+3
renvoie 5, mais "2"+"3"
renvoie "23"
. Si cet opérateur agit sur une chaîne et un nombre, alors ce dernier est transformé en chaîne : "un"+2
renvoie donc "un2"
et 2+"3"
renvoie "23"
.
-
permet de faire la soustraction de deux nombres. JavaScript
gère les conversions de types à la volée dans ce cas, et "7"-2
renvoie 5
*
permet de faire la multiplication de deux nombres. 9*2
renvoie donc 18
. JavaScript
gère aussi les conversions de types à la volée dans ce cas, et "9"*2
renvoie aussi 18
.
/
permet de faire la division du premier nombre par le second. 9/2
renvoie donc 4.5
. JavaScript
gère aussi les conversions de types à la volée dans ce cas, et "7"/2
renvoie 3.5
.
%
renvoie le reste de la division euclidienne de deux nombres. Par exemple, 9 % 2
renvoie 1
. JavaScript
opère la conversion de type aussi dans ce sens : "9" % 2
renvoie aussi 1
. Cette opérateur fonctionne aussi avec les nombres à virgule flottante : 20.4%4.8
renvoie 1.2
(ou plutôt 1.1999999999999993
selon les arrondis de calcul).
Les opérateurs binaires de comparaison permettent de réaliser des tests sur des variables ou des données. Leur valeur de sortie est un booléen. Ces opérateurs sont :
<
permet de tester si le premier nombre est strictement inférieur au second : 1<2
renvoie true
, mais 1<1
. renvoie false
.
<=
permet de tester si le premier nombre est inférieur ou égal au second : 1<=2
renvoie true
ainsi que 1<=1
.
>
permet de tester si le premier nombre est strictement supérieur au second : 1>2
renvoie false
.
>=
permet de tester si le premier nombre est supérieur ou égal au second : 1>=2
renvoie false
.
==
permet de tester l'égalité de deux nombres : 1==2
renvoie false
. JavaScript
gère la conversion de type et 1=="1"
renvoie true
.
!=
permet de tester si deux nombres sont différents : 1!=2
renvoie true
.
===
permet de tester à la fois le type et l'égalité de deux expressions : 1===2
renvoie false
, . 1===1
renvoie true
mais 1==="1"
renvoie false
, puisque l'on compare un nombre à une chaîne de caractères.
!==
permet de tester si deux expressions sont de types différents ou de valeurs différentes (c'est l'opérateur inverse de ===
).
Ces opérateurs renvoient aussi des booléens, et opèrent sur des booléens.
&&
est le "et logique", et renvoie true
quand les deux quantités sur laquelle il opère valent true
. Par exemple, (1<2) && (chaine == "a")
renvoie true
si la variable chaine
vaut "a"
, et false
dans le cas contraire.
||
est le "ou logique", et renvoie true
quand au moins une des deux quantités sur laquelle il opèrent vaut true
. Par exemple, (1<2) || (chaine == "a")
renvoie true
dans tous les cas, car 1<2
est toujours vrai.
Les opérateurs unaires s'appliquent à une seule quantité. Il y en a trois.
!
est l'opérateur logique de négation, et s'applique aux booléens. Ainsi, !(1<2)
renvoie false
.
++
est l'opérateur d'incrémentation : il ajoute 1 à la variable concernée. Par exemple, si a
vaut 2, alors a++
affecte 3 à a
. Cet opérateur peut être placé en préfixe ou en postfixe (comme dans cet exemple). Voir ci-après pour plus de détails.
--
est l'opérateur de décrémentation : il soustrait 1 à la variable concernée. Par exemple, si a
vaut 2, alors --a
affecte 1 à a
. Cet opérateur peut être placé en préfixe (comme dans cet exemple) ou en postfixe. Voir ci-après pour plus de détails.
La position des opérateurs d'incrémentation ou de décrémentation est importante dans le cas d'un calcul. Lorsque l'opérateur est en position de préfixe, l'opération est réalisée avant tout calcul. Lorsqu'il est en postfixe, l'opération est réalisée à la toute fin du calcul. Voici quelques exemples :
var
a=3 ;
b=(a++)*2 ;
var
a=3 ;
b=(++a)*2 ;
Le premier exemple effectue d'abord la multiplication de a
par 2, puis incrémente a
. On obtient donc b=(3)*2=6. Le second exemple incrémente d'abord a
, puis multiplie le résultat par 2. On obtient donc b=(3+1)*2=8. Dans les deux cas, la valeur finale de a
est 3+1=4.
Il n'est pas dans le propos de ce cours de faire une initiation complète à la Programmation Orientée Objet, mais d'en présenter les quelques points qui sont utiles au jour le jour en JavaScript
. Nous reviendrons plus en détails dans un autre chapitre sur la manière de manipuler des objets en JavaScript
.
Un objet est une entité de programmation qui possèdent un certain nombre de propriétés, et sur laquelle il est possible d'agir ou qui est susceptible d'agir par l'intermédiaire de méthodes. Une méthode est une sorte de fonction s'appliquant à l'objet, et à la syntaxe un peu particulière.
Une propriété caractérise un objet. Par exemple, si l'on pense à un objet physique comme une boîte, ses propriétés pourraient être ses longueur, hauteur et profondeur, sa couleur, le fait qu'elle soit ouverte ou fermée, pleine ou vide, etc. Des méthodes permettant d'interagir avec cette boîte seraient par exemple l'action de l'ouvrir ou de la fermer (qui agirait sur la propriété « ouverte ou fermée »), celle d'y ajouter ou d'en extraire du contenu (qui agirait sur la propriété « pleine ou vide »), etc. En JavaScript
comme dans les autres langages orientés objet, on représente les propriétés et les méthodes avec des points. Pour reprendre notre exemple de boîte, une implémentation Javascript
en serait :
boite.longueur ;
boite.hauteur ;
boite.profondeur ;
boite.couleur ;
boite.ouverte ;
boite.pleine ;
boite
ouvrir() ;
boite
fermer() ;
boite
remplir(contenu) ;
boite
vider() ;
Nous allons voir des exemples de propriétés et de méthodes pour des objets que l'on utilise très souvent en JavaScript
.
Cet objet ne possède qu'une seule propriété, length
, qui renvoie sa longueur. Ainsi, chaine="Bonjour!";alert(chaine.length);
renvoie 8.
Les méthodes de cet objet permettent de manipuler les chaînes de caractères. Elles s'appliquent à toute variable de ce type.
indexOf
renvoie la position de la première occurrence d'un caractère donné dans une chaîne. Ainsi, chaine="Bonjour!";alert(chaine.indexOf('o'));
renvoie 1, la numéroration commençant à 0. Si le caractère n'est pas trouvé, la méthode renvoie -1.
lastIndexOf
renvoie la position de la dernière occurrence d'un caractère donné dans une chaîne. Ainsi, chaine="Bonjour!";alert(chaine.lastIndexOf('o'));
renvoie 4.
charAt
renvoie le caractère présent à une certaine position. Par exemple, chaine="Bonjour!";alert(chaine.charAt(5));
renvoie « u ».
charCodeAt
renvoie le code Unicode du caractère présent à une certaine position. Par exemple, chaine="Bonjour!";alert(chaine.charCodeAt(5));
renvoie « 117 ».
fromCharCode
renvoie une chaîne correspondant à la séquence de codes Unicode passée en paramètre. Par exemple, alert(String.fromCharCode(66, 111, 110, 106, 111, 117, 114, 33))
renvoie « Bonjour! ».
La méthode toUpperCase
convertit la chaîne en majuscules. Par exemple, chaine="Bonjour!";alert(chaine.toUppercase);
affiche « BONJOUR! ».
À l'inverse, la méthode toLowerCase
convertit la chaîne en minuscules. Par exemple, chaine="Bonjour!";alert(chaine.toLowercase);
affiche « bonjour! ».
La méthode substring
extrait une sous-chaîne de la chaîne à laquelle elle s'applique. Cette méthode prend deux entiers positifs en paramètres. Le paramètre le plus petit indique la position de départ dans la chaîne (commençant à 0), le paramètre le plus grand la position de fin (le caractère de cette position ne fait pas partie du résultat). Par exemple, chaine="Bonjour!";alert(chaine.substring(1,4);
renvoie « onj ».
substr
extrait aussi une sous-chaîne, mais elle fonctionne différemment. Ainsi, le premier paramètre désigne la position de départ, et le second indique la longueur de la sous-chaîne à extraire. Par exemple, chaine="Bonjour!";alert(chaine.substr(1,4));
renvoie « onjo ».
slice
extrait aussi une sous-chaîne, mais elle fonctionne encore différemment. Ainsi, le premier paramètre désigne la position de départ, et le second indique la position de fin de la sous-chaîne à extraire. Par exemple, chaine="Bonjour!";alert(chaine.substr(2,4));
renvoie « njo ». Si le second paramètre est omis, slice
extrait la sous-chaîne jusqu'à la fin : chaine="Bonjour!";alert(chaine.slice(2));
renvoie donc « njour! »
split
permet de scinder une chaîne en sous-chaînes en utilisant le paramètre comme caractère de séparation. Le résultat est un tableau de chaînes de caractères. Ainsi, chaine="Bonjour!";tab=chaine.split('o');
renvoie un tableau à une dimension dont les éléments sont respectivement "B"
, "nj"
et "ur!"
.
concat
concatène la chaîne avec la ou les chaînes passées en argument. Par exemple, chaine="Bonjour!";alert(chaine.concat(" et à ", "bientôt…"));
renvoie « Bonjour! et à bientôt… ».
replace
remplace un morceau de la chaîne indiqué en paramètre par une autre chaîne indiquée comme second paramètre. Par exemple, chaine="Bonjour!";alert(chaine.replace("jour", "soir"));
renvoie « Bonsoir! ».
includes
teste si une chaîne de caractères donnée est incluse dans une autre, et renvoie un booléen. Par exemple…
var chaine="Liberté, égalité, fraternité" ;
chaine.includes("Liberté");//true
chaine.includes("Solidarité");//false
chaine.includes("Fraternité");//false
chaine.includes("fraternité");//true
match
sélectionne les parties d'une chaîne qui correspondent à une expression rationnelle. Par exemple (exemple tiré de la Référence Javascript 1.5 de la Fondation Mozilla) :
var str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" ;
var regexp = /[A-E]/gi ;
var matches_array = str.match(regexp) ;
alert(matches_array) ;
search
recherche une expression rationnelle dans la chaîne à laquelle elle s'applique, et renvoie l'index de cette expression.
Il est courant de devoir faire appel à des fonctions ou des constantes mathématiques dès lors que l'on souhaite réaliser quelques calculs. Plusieurs sont disponibles à l'aide de cet objet (ne pas oublier la majuscule à Math
!).
E
est la constante d'Euler (environ 2,718)
PI
est le nombre pi (environ 3,14159)
LN2
est le logarithme naturel de 2 (environ 0,693)
LN10
est le logarithme naturel de 10 (environ 2,302)
LOG2E
est le logarithme en base 2 de e (environ 1,442)
LOG10E
est le logarithme en base 10 de e (environ 0,434)
SQRT2
est la racine carrée de 2 (environ 1,414)
SQRT1_2
est la racine carrée de 1/2 (environ 0,707)
Ces méthodes correspondent à des fonctions mathématiques.
abs
retourne la valeur absolue du paramètre
cos
, sin
et tan
renvoient respectivement le cosinus, le sinus et la tangente du paramètre (celui-ci doit être indiqué en radians).
acos
, asin
et atan
renvoient respectivement l'arccosinus, l'arcsinus et l'arctangente du paramètre, exprimé en radians.
atan2
renvoie l'arctangente du rapport de ses deux paramètres (c'est-à-dire l'angle en radians dont la tangente est égale au rapport des deux paramètres).
ceil
renvoie le plus petit entier supérieur ou égal à son argument. Par exemple, ceil(3.7)
et ceil(3.2)
renvoient 4.
floor
renvoie le plus grand entier inférieur ou égal à son argument. Par exemple, floor(3.7)
et floor(3.2)
renvoient 3.
round
renvoie l'entier le plus proche de son argument. Par exemple, round(3.7)
renvoie 4 et round(3.2)
renvoie 3.
exp
renvoie l'exponentielle de son argument
log
renvoie le logarithme naturel de son argument. Par exemple, alert(Math.log(Math.E));
renvoie 1.
max
et min
renvoient respectivement le plus grand et le plus petit nombre d'une collection de nombres. Par exemple, alert(Math.max(1,2))
renvoie 2.
pow
élève à la puissance du second paramètre le nombre passé en premier paramètre. Par exemple, alert(Math.pow(2,3))
renvoie 8.
sqrt
renvoie la racine carrée de son argument
random
renvoie un nombre pseudo-aléatoire compris entre 0 et 1.
Date
est un type d'objet qui permet de gérer non seulement les dates, mais aussi les heures et durées. Le constructeur est ce qui permet de créer une nouvelle « instance » de la classe Date
. Sa syntaxe est
var nouvelleDate = new Date(annee, mois, jour [, heure, minute, seconde, milliseconde]) ;
Les paramètres heure
, minute
, seconde
et milliseconde
sont optionnels. Par exemple, une variable stockant la date du 11 octobre 2003 à 9h32 passée de 34 secondes et 123 millisecondes est créée par…
var nouvelleDate = new Date(2003, 9, 11, 9, 32, 34, 123) ;
Si aucun paramètre n'est utilisé, par exemple auj=new Date;
, la date renvoyée est la date courante.
Tous les exemples ci-dessous sont donnés avec l'objet nouvelleDate
tel qu'il a été créé plus haut. Les méthodes de Date
sont :
getFullYear
renvoie l'année pour la date spécifiée. Ainsi, alert(nouvelleDate.getFullYear())
renvoie 2003. Cette méthode est complétée par getUTCFullYear
qui donne l'année dans le Temps Universel en tenant compte du décalage horaire.
getMonth
renvoie le mois pour la date spécifiée. Ainsi, alert(nouvelleDate.getMonth())
renvoie 9, la numérotation des mois commençant en janvier à 0. Cette méthode est complétée par getUTCMonth
qui donne l'année dans le Temps Universel en tenant compte du décalage horaire.
getDate
renvoie le quantième dans le mois pour la date spécifiée. Ainsi, alert(nouvelleDate.getDate())
renvoie 11. Cette méthode est complétée par getUTCDate
qui donne l'année dans le Temps Universel en tenant compte du décalage horaire.
getDay
renvoie le jour de la semaine pour la date spécifiée (0=dimanche, 6=samedi). Ainsi, alert(nouvelleDate.getDay())
renvoie 6. Cette méthode est complétée par getUTCDay
qui donne l'année dans le Temps Universel en tenant compte du décalage horaire.
getHours
renvoie l'heure dans le jour pour la date spécifiée (entre 0 et 23). Ainsi, alert(nouvelleDate.getHours())
renvoie 9. Cette méthode est complétée par getUTCHours
qui donne l'année dans le Temps Universel en tenant compte du décalage horaire.
getMinutes
renvoie le nombre de minutes pour la date spécifiée. Ainsi, alert(nouvelleDate.getMinutes())
renvoie 32. Cette méthode est complétée par getUTCMinutes
qui donne l'année dans le Temps Universel en tenant compte du décalage horaire.
getSeconds
renvoie le nombre de secondes pour la date spécifiée. Ainsi, alert(nouvelleDate.getSeconds())
renvoie 34. Cette méthode est complétée par getUTCSeconds
qui donne l'année dans le Temps Universel en tenant compte du décalage horaire.
getMilliseconds
renvoie le nombre de millisecondes pour la date spécifiée. Ainsi, alert(nouvelleDate.getMilliseconds())
renvoie 123. Cette méthode est complétée par getUTCMilliseconds
qui donne l'année dans le Temps Universel en tenant compte du décalage horaire.
getTime
renvoie le nombre de millisecondes écoulées depuis le 1er janvier 1970 jusqu'à la date spécifiée.
getTimezoneOffset
renvoie le déclarage horaire en minutes par rapport au Temps Universel tel qu'il est défini sur le système d'exploitation. Par exemple, si l'on se trouve dans une zone à GMT+10, la valeur retournée est -600.
Chacune de ces méthodes a son pendant permettant de spécifier la propriété correspondante (par exemple setDate
en parallèle de getDate
).
toLocaleString
convertit une date en chaîne de caractères en utilisant les conventions locales. Cette méthode est complétée par toLocaleDateString
et toLocaleTimeString
pour la date et l'heure. Attention, cette méthode n'estv pas recommandée en production, car elle ne renvoie pas une chaîne de caractères sous un format standard, aisé à manipuler. Le résultat dépend du système d'exploitation et du navigateur.
Nous reviendrons sur l'objet
window
plus loin dans ce cours. Pour le moment, voici trois méthodes d'un usage courant, permettant de gérer les interactions avec l'utilisateur :
alert(chaine)
affiche à l'écran le message d'information contenu dans chaine
. Dans la boîte ne se trouve qu'un bouton OK
.
confirm(chaine)
affiche la chaîne de caractères chaine
accompagnée de deux boutons OK
et Annuler
. Cette méthode renvoie un booléen qui vaut true
si OK a été cliqué, et false
si l'utilisateur a cliqué sur Annuler
.
prompt(chaine)
affiche la chaîne de caractères chaine
puis une champ de saisie. La méthode retourne sous la forme d'une chaîne de caractères le résultat de la saisie de l'utilisateur. Si l'on souhaite traiter cette sortie comme un nombre, il est nécessaire de passer par la fonction parseInt
. Par exemple, quantite=prompt("Entrez la quantité souhaitée :");
On peut parfois avoir besoin d'ajouter des propriétés ou des méthodes aux objets prédéfinis. Par exemple, on peut souhaiter mettre en majuscule la première lettre de n'importe quelle chaîne. Il est possible de le faire en étendant les propriétés et méthodes prédéfinies, à l'aide de la propriété prototype
:
//On vérifie que la propriété n'existe pas déjà…
if (!String.prototype.capitalize)
{
String.prototype..capitalize = function()
{
return
this.charAt(0).toUpperCase()+this.slice(1).toLowerCase() ;
}
}
Il suffit alors d'appeler cette nouvelle méthode comme n'importe quelle autre, par exemple : var test="Essai";alert(test.capitalize());
Cependant, définir de la sorte une méthode n'est pas sans effet secondaire. En effet, si on exécute une simple boucle var chaine="hep"; for (var i in chaine) console.log(i+" : "+chaine[i])
, on obtient successivement les chaînes de caractères "h"
, "e"
et "p"
mais aussi pour finir capitalize: function () { return this.charAt(0).toUpperCase()+this.slice(1).toLowerCase() ; }
. Afin d'éviter cet effet de bord gênant, on doit explicitement déclarer que cette méthode n'est pas énumérable :
//On vérifie que la propriété n'existe pas déjà…
if (!String..prototype..capitalize)
{
Object.defineProperty(String..prototype,'capitalize',
{
value : function()
{
return
this..charAt(0)..toUpperCase()+this..slice(1)..toLowerCase() ;
} ,
enumerable: false
}) ;
}
Les tests logiques permettent de réaliser des opérations en fonction des conditions dans lesquelles le code s'exécute. Par exemple, si l'utilisateur a entré un prénom féminin en guise d'identifiant, on peut envisager d'accorder les participes passés en fonction de ce choix.
L'instruction if
est la plus simple possible. Elle permet de tester une condition unique. Par exemple,
if (choix == 1)
{
alert("Vous avez fait le premier choix") ;
}
Elle peut être complétée par l'instruction else
, qui permet d'indiquer le code à exécuter si la condition n'est pas remplie :
if (choix == 1)
{
alert("Vous avez fait le premier choix") ;
}
else
{
alert("Vous n'avez pas fait le premier choix") ;
}
Cette instruction permet de réaliser des branchements conditionnels. Elle s'utilise avec le mot-clef case
. Chaque cas est analysé, puis si le test est concluant, la liste d'instructions suivant le case
est exécutée. Cette exécution se poursuit jusqu'à rencontrer l'instruction break
. On indique la liste des instructions à réaliser par défaut avec default
. Par exemple,
switch (choix)
{
case 1:
alert("Vous avez fait le premier choix") ;
break ;
case 2:
alert("Vous avez fait le deuxième choix") ;
break ;
case 3:
alert("Vous avez fait le troisième choix") ;
break ;
default :
alert("Vous avez fait un choix au moins égal à 4") ;
}
Si on avait omis le break
à la fin du troisième case
, si l'utilisateur avait saisi 3 on aurait eu coup sur coup l'affichage des messages "Vous avez fait le troisième choix" et "Vous avez fait un choix au moins égal à 4".
Les itérations sont des séries d'instructions qui doivent être exécutées de manière répétitive, un certain nombre de fois ou bien jusqu'à ce qu'une condition soit réalisée. Quatre instructions sont disponibles : do… while
, while
, for
et for… in
Ces deux instructions jouent des rôles similaires. Une série d'instructions est répétée tant qu'une condition est réalisée. Par exemple…
var compteur = 1 ;
do
{
compteur++ ;
alert(compteur) ;
}
while (compteur<3)
Le code précédent affichera successivement 2 puis 3 avant de sortir de la boucle. Il en est de même pour…
var compteur = 1 ;
while (compteur<3)
{
compteur++ ;
alert(compteur) ;
}
La différence vient du fait que do… while
exécutera l'ensemble d'instructions au moins une fois. Ainsi…
var compteur = 1 ;
do
{
compteur++ ;
alert(compteur) ;
}
while (compteur<1)
… affichera 2 une fois avant de sortir de la boucle. En revanche…
var compteur = 1 ;
while (compteur<1)
{
compteur++ ;
alert(compteur) ;
}
… n'affichera rien du tout.
Deux types de boucles for
existent en JavaScript
. Ces boucles s'effectuent un nombre déterminé de fois. La plus simple à concevoir est par exemple la boucle…
for (var i=0;i<3;i++)
{
//Suite d'instructions…
}
La syntaxe générale de la parenthèse après le mot-clef for
est
instruction de départ ;
condition de fin ;
instruction à exécuter à chaque fin d'itération.
La dernière instruction est souvent limitée à une incrémentation, mais lorsque la boucle ne comporte qu'une seule instruction, il est possible de l'y placer.
Une variante de la boucle for
est la boucle for… in
. Cette boucle permet de parcourir un tableau ou plus généralement un objet. Par exemple,
var tab = new Array(3) ;
for (element in
tab)
{
element="test" ;
}
L'exemple précédent crée un tableau de trois chaînes de caractères, dont chaque élément contient la chaîne "test"
.
Ces deux méthodes de l'objet window
permettent d'indiquer une liste d'instructions à exécuter au bout d'un certain temps. Par exemple,
function fonctionTest(i)
{
while (i>0)
{
alert(i) ;
setTimeout("fonctionTest(i)", 1000) ;
}
i-- ;
}
Le second paramètre est le temps au bout duquel le premier paramètre doit être évalué, exprimé en millisecondes. Ici, fonctionTest(3)
affichera toutes les secondes successivement 3, puis 2, puis 1 avant de s'arrêter. setTimeout
renvoie un entier servant à identifier l'appel à cette méthode, et il est possible de stopper ces répétitions à l'aide de la méthode clearTimeout(identifiant)
.
La méthode setInterval
, qui renvoie un entier servant d'identifiant, permet de relancer une fonction à intervalles de temps réguliers (exprimés en millisecondes). Le code suivant relance la fonction fonctionARepeter
toutes les secondes.
identifiant=setInterval("fonctionARepeter()", 1000) ;
L'identifiant retourné permet de stopper ces répétitions à l'aide de la méthode clearInterval
.
Il est possible de demander à ce qu'une expression soit évaluée à la saisie, à l'aide de la fonction eval()
. Par exemple, eval("a=3+2;alert(a);")
affiche 5 dans une boîte d'alerte. Attention : cette fonction est à utiliser avec précaution, pour des raisons de sécurité.
Cette création est mise à disposition par Gilles Chagnon sous un contrat Creative Commons.