Introduction au langage§
Pierre-Antoine Champin & Michael Mrissa
Département Informatique, IUT Lyon 1Ce travail est sous licence Creative Commons Attribution-ShareAlike 3.0 France.
Pierre-Antoine Champin & Michael Mrissa
Département Informatique, IUT Lyon 1Ce travail est sous licence Creative Commons Attribution-ShareAlike 3.0 France.
<video>
, :hover
...).if (i < 10) {
j = j+1;
k += i;
} else {
j = 0;
}
while (i < 10) {
j = j*i;
i += 1;
}
for(i=0; i<10; i+=1) {
j = j*i;
}
if (i < 0) {
throw new Error("negative value");
}
try {
i = riskyFunction();
}
catch (err) {
i = -1;
}
a = [1,2,3,5,8,13];
for (i=0; i < a.length ; i+=1) {
console.log(a[i]);
}
// affiche tous les éléments du tableau
Indication
Comme en Python et contrairement à Java, les tableaux en JS peuvent changer de taille (voir leur documentation pour plus de détails)
Avertissement
Contrairement à Python, un tableau vide (de longueur 0)
est équivalent à true
dans une condition.
Il existe cependant des différences importantes que vous devez connaître.
Indication
JSHint peut être installé sur votre machine, mais peut également être utilisé directement en ligne.
txt
est une chaîne de catactères,
txt[i]
retourne également une chaîne de caractères de longueur 1.'
) ou doubles ("
)
peuvent être utilisés indifféremment pour délimiter les chaînes de caractères.Remarque
Ces particularités sont partagées avec d'autres langage dynamiquement typés, comme par exemple Python.
En Java (comme en C), les variables et les fonctions ont un type fixé :
int fact(int n) {
int r = 1;
for(int i=1; i<=n; i+=1) {
r *= i;
}
return r;
}
En Javascript (comme en Python), on ne spécifie pas le type des variables ou des fonctions :
function fact(n) {
let r = 1;
for(let i=1; i<=n; i+=1) {
r *= i;
}
return r;
}
Indication
Remarquez le mot-clé let
devant les premières utilisations des variables r
et i
.
Vocabulaire
On parle de typage dynamique, car cela permet à une variable de contenir (par exemple) un entier à un moment, et une chaîne de caractères à un autre moment. De la même manière, une fonction pourra retourner (par exemple) tantôt un flottant, tantôt un entier.
Cette flexibilité est utile dans certains cas, même si bien sûr il ne faut pas l'utiliser pour faire n'importe quoi...
Contrairement aux autres langages dynamiquement typés,
Javascript demande que les variables locales soient déclarées,
avec un mot-clé let
, const
ou var
(ce dernier est
de moins en moins utilisé). Lorsqu'une variable est déclarée
avec le mot-clef const
, elle doit être immédiatement
initialisée et ne peut être réaffectée.
Indication
Les paramètres des fonctions font exception à cette règle, puisqu'ils sont déclarés par leur présence dans l'en-tête de la fonction.
Avertissement
Un oubli du mot-clé est dangereux, car il ne constitue pas une erreur. Mais, dans ce cas, la variable est considérée comme globale, ce qui peut créer des bugs difficiles à détecter, comme le montre cet exemple.
Indication
JSHint détecte ce type d'erreur dans la plupart des cas, à condition d'activer le contrôle ainsi :
// jshint undef:true
En JS, on teste l'égalité avec l'opérateur ===
,
et l'inégalité avec l'opérateur !==
:
if (i === j && i !== k) // ...
Avertissement
Les opérateurs habituels ==
et !=
existent aussi,
mais ils ont une sémantique très inhabituelle,
et sont donc généralement évités.
Indication
JSHint détecte toute utilisation de ==
ou !=
à
condition d'activer le contrôle ainsi :
// jshint eqeqeq:true
Avertissement
En fait, l'opérateur ==
considère que
deux valeurs de types différents sont égales
si on peut passer de l'une à l'autre par conversion de type.
Par exemple :
"42" == 42 // est vrai
C'est un problème, car cela conduit à des choses contre-intuitives :
if (a == b && b == c) {
a == c; // peut être faux
// par exemple : a = "0", b = 0, c = "" ;
// en effet, 0 et "" sont tous deux équivalents à false
}
Avertissement
ou encore :
if (a == b) {
a+1 == b+1; // peut être faux
// par exemple : a = "42" (a+1 == "421") et b = 42 (b+1 == 43)
}
null
et undefined
§null
et undefined
.Indication
Les deux sont équivalentes à false
dans une condition.
En Javascript,
l'accès à un élément inexistant dans un tableau ou un objet
ne déclenche pas d'erreur,
mais retourne simplement undefined
.
Ceci cause en général une erreur ailleurs dans le code, ce qui le rend plus difficile à déboguer :
let a = ["Alice", "Bob", "Charlie"];
let n = a[5]; // n reçoit undefined
if (n.length > 32) { // erreur : undefined n'a pas de longueur
// ...
}
console.log(message)
Avertissement
Comme son nom l'indique, la console développeur est déstinée au développeur,
pas à l'utilisateur final (qui n'ouvre pas la console).
L'utilisation de console.log
doit donc être réservée aux messages de debug.
main
) décrit dans quel ordre
les différentes fonctions du programme doivent s'exécuter.<p>Hello <span onmouseover="console.log('haha, tickles');">world</span></p>
<button onclick="console.log('click');">Click me</button>
Indication
Pour voir ce qui s'affiche sur la console, pressez CTRL+SHIFT+J (sous Chrome) ou CTRL+SHIFT+K (sous Firefox).
1<p>Hello <span onmouseover="f1();">world</span></p>
2<button onclick="f2();">Click me</button>
3
4<script>
5 function f1() {
6 console.log('haha, tickles');
7 }
8 function f2() {
9 console.log('click');
10 }
11</script>
<p>Hello <span onmouseover="f1();">world</span></p>
<button onclick="f2();">Click me</button>
<script src="s1_script_externe.js"></script>
Essayez cet exemple, ou modifiez-le.
Le standard HTML5 définit un large éventail d'événements que le code Javascript peut intercepter :
Indication
Dans le code HTML,
les attributs correspondants ont toujours la forme onX
où X
est le nom de l'événement.
document
§La variable globale document
contient un objet représentant le document HTML.
Elle permet d'accéder aux éléments du document :
getElementsByTagName(tagname)
:tagname
getElementById(id)
:id
querySelector(cssSelector)
:querySelectorAll(cssSelector)
:document
§Remarque
On définira la notion d'élément plus en détail la semaine suivante, dans la partie sur L'arbre DOM.
Indication
Il est plus efficace d'utiliser les méthodes getElement*
que d'utiliser querySelector*
avec les sélecteurs correspondants
(tagname
ou #identifier
).
addEventListener(eventname, func)
:func
à l'événement eventname
sur cet élémenttextContent
:style
:permet de consulter et modifier l'attribut style
de l'élément,
sous forme d'un objet ayant un attribut pour chaque propriété CSS.
(e.g. e.style.fontSize
pour la propriété font-size
)
Syntaxe
Pour faciliter l'utilisation en Javascript,
la typographie des attributs de style
n'est pas la même que celle des propriétés CSS correspondantes.
Les tirets (-
) sont remplacés par une mise en majuscule de la lettre suivante
(CamelCase).
classList
:
permet de consulter et modifier l'attribut
class
de l'élément, grâce aux méthodes suivantes :
add(cls)
: ajoute la classe cls a l'élément.remove(cls)
: retire la classe cls a l'élément.contains(cls)
: indique si l'élément possède actuellement la classecls
.toggle(cls)
: inverse l'état de la classe cls (présente/absente) sur l'élément.
Bonne pratique
Comme en HTML+CSS,
il est préférable de spécifier la mise en forme à l'aide de classes dans le CSS,
et de modifier ces classes dans le code Javascript,
plutôt que la spécifier directement dans le code Javascript à travers l'attribut style
.
Les éléments possèdent de nombreux autres attributs; en particulier, chaque attribut HTML a une contrepartie en Javascript.
On peut notamment citer :
href
(pour les <a>
)src
(pour les <img>
)value
(pour les <input>
)disabled
(pour tous les éléments de formulaire)checked
(pour les cases à cocher)... sur cet exemple.
<p>Hello <span>world</span></p>
<button id="b1">Click me</button>
<script src="s1_script_externe.js"></script>
// définition de f1 et f2 comme précédemment, puis...
document.getElementsByTagName('span')[0]
.addEventListener('mouseover', f1);
document.getElementById('b1')
.addEventListener('click', f2);
Avertissement
Le nom de l'événement, passé à addEventListener
,
ne doit pas comporter le préfixe on
.
On écrira donc addEventListener('click', ...)
,
et non addEventListener('onclick', ...)
.
Bonne pratique
Ceci est la bonne manière d'abonner une (ou plusieurs) fonctions(s) à des événements, notamment parce qu'elle permet de séparer l'aspect structurel (HTML) de l'aspect dynamique (Javascript).
Les manières présentées précédemment vous ont été présentées
Mais il vous est fortement déconseillé de les utiliser dans du code que vous écrivez vous-mêmes.
getElement*
peuvent échouer.load
,
et il est accessible sur l'objet window
,
qui représente la fenêtre du navigateur.Indication
Contrairement aux éléments HTML,
l'objet window
existe forcément dès l'exécution du Javascript,
donc on peut sans risque s'abonner à ses événements.
1// définition des fonctions f1 et f2, puis...
2
3function cree_abonnements() {
4 document.getElementsByTagName('span')[0]
5 .addEventListener('mouseover', f1);
6 document.getElementById('b1')
7 .addEventListener('click', f2);
8}
9
10window.addEventListener("load", cree_abonnements);
NB : Vous pourriez trouver utile l'annexe ci-après.
Une expression régulière (ou regexp) décrit dans une syntaxe spécialisée une famille de chaînes de caractères.
Par exemple :
[a-z]{1,5}
: un mot de 1 à 5 lettres\d{2}/\d{2}/\d{4}
: une date (jj/mm/aaaa)[a-z]+@[a-z]+(\.[a-z]+)*
: une adresse e-mailIndication
Les expressions régulières sont utilisables dans tous les langages de programmation, mais elles sont particulièrement bien intégrées à Javascript.