Plus d'explications
Jusqu'ici tout ce que l'on a vu est soit une variable, soit une valeur, soit une fonction, soit un mot-clef. Pour le moment tout ceci ne vous dis pas grand chose mais expliquer ca est le but de ce chapitre.
Les valeurs
Ça c'est le plus simple, peut être même trop simple. 5
c'est une valeur, false
c'est une valeur, "un peu de texte"
est aussi une valeur. Le but d'un programme informatique est de manipuler des valeurs (souvent fournies par l'utilisateur) rapidement pour calculer et/ou partager de l'information.
Pour le moment on va se dire qu'il existe 3 type de valeurs différentes. On verra les autres plus tard.
- Les nombres:
5
,-12
,13.37
- la valeur de vrai
true
et la valeur de fauxfalse
, que l'on appelle "valeurs booléennes" d'après George Boole qui s'est dit "viens on éssaye de faire des maths avec vrai/faux plutôt que des nombres, comme ça on pourra rigouresement calculer si un argumentaire est correct ou non". - les textes:
"ceci est du texte"
,"ça aussi"
,'on peut aussi mettre ça entre guillemets simples'
. Sachez c'est quasiment tout le temps appelé une "string", du terme technique "string of characters" qui veux dire "chaîne de caractères".
Attention au guillemets
J'insiste parceque ça arrive régulièrement que de confondre un nombre 5
avec du texte représentant ce nombre "5"
. Ce qui n'est pas pareil.
Exécutez le code ci-dessous pour voir le résultat.
console.log(5 + 5);
console.log("5" + "5");
console.log(5 + "5");
Remarquez que l'opération +
permet de coller deux bouts de texte ensemble en un plus gros bout de texte, et vu que ça ne fait aucun sense de chercher à additionner un nombre et du texte, javascript prévois dans ce cas de convertir le nombre en texte puis de les coller ensemble. Ce qui fâche beaucoup de programmeurs qui préféreraient qu'on leur refuse et qu'on les avertisse à la place.
Les variables
let
mais aussi const
Une variable permet de garder une valeur en memoire, c'est bien pratique si on veux s'en servir plusieurs fois. Que soit parce que sa valeur pourrait changer entre deux utilisations comme on a vu avec la variable count
au chapitre précédent, ou juste parce que c'est plus facile de donner un nom explicite a une valeur pour ensuite s'en servir à plusieur endroits du code.
let
est le mot-clef qui nous permet de créer une variable à laquelle on pourra réassigner une nouvelle valeur plus tard dans le code comme ceci.
let a = 5;
a = a * 2;
console.log(a); // 10
c'est assez pratique quand il s'agit de données sur lesquelles ont est "en cours de travail".
Pour faciliter la lisibilité d'un programme on pourrait vouloir créer une variable qui n'as pas pour vocation de changer mais juste de mettre un nom sur une valeur.
Si je vous montre ...
console.log(42); // 42
... ainsi que ceci
let userAge = 42;
console.log(userAge); // 42
Le programme nous donne le même résultat, 42
dans la console. Mais dans le deuxième, en tant que développeur, vous comprennez qu'on déclare que l'âge de l'utilisateur est de 42
puis on s'affiche l'âge de l'utilisateur, ce qui communique clairement plus sur le fonctionnement du programme que le premier exemple.
Mais avoir toutes les variables de son programme qui ont la capacité de changer ça n'est pas nécessaire et notre programme s'exécute tellement vite que l'utilisteur n'aura pas le temps de fêter son anniversaire qu'on aura déjà fini. On peut juste remplacer let
par const
pour s'assurer qu'aucune ligne de code pourra changer la valeur de userAge
en cours de routes.
const userAge = 42;
console.log(userAge); // 42
Je sais que cet exemple n'est pas très convaincant, mais imaginez que maintenant on parle d'une variable qui existe au travers de tout le programme et que ce programme fait 400 lignes, tout de suite c'est plus intéressant de se garantir que la variable ne peut pas changer, ça nous débarasse d'un paquet d'ennuis potentiel.
De manière générale, commencez toujours par créer vos variables avec const
puis de les changer pour let
si vraiment c'est utile.
undefined
Un nouveau type de valeur à ajouter à votre liste.
undefined
(non-defini) est une valeur spéciale. Si on créer une variable sans pour autant lui donner de valeur alors sa valeur initiale sera undefined
.
let a;
console.log(a); // undefined
En soi, cette valeur ne vous sert à rien mais au moins quand vous verrez l'erreur ci-dessous ça vous parlera un peu plus.
Trouvez le bug:
let a;
let b;
const c;
a = 5;
b = a + 5;
c = a + b;
Solution
Il est trop tard pour donner a + b
comme valeur à c
car au moment de sa création il a déjà reçu undefined
comme valeur et vu que c'est une variable const
on ne peut plus lui donner autre chose.
D'ailleurs, je remarque en écrivant ça que les navigateurs sont suffisamment intélligents et ne vous laissent même pas aller jusqu'à la dernière ligne. Effectivement, ne pas donner de valeur lors de la création d'une constante est littéralement inutile et donc ils ont prévu de crasher dans ce scenario.
Une valeur, certes, mais une valeur complexe
Je vous avais dit qu'une variable permet contenir une valeur, et je ne vous ai pas menti. Mais il existe un type de valeur que nous n'avons pas encore vu, qui est utilisé quasiment partout, et qui représente la majeure complexité du chapitre précédent.
Les objets.
Un objet est une valeur qui contient d'autre valeurs et qui se présente comme ceci.
{
name: "John Oates",
birth: 1948,
retired: false,
occupation: "out of time",
}
C'est toujours délimité par des accolades {}
et chaque chose contenue présente d'abord son nom puis deux-points :
puis la valeur et une virgule ,
, la virgule de la derniere ligne n'étant pas obligatoire.
Les retours à la ligne ne sont pas obligatoires, on pourrait le marquer comme ceci ...
{ name: "John Oates",birth: 1948, retired: false, occupation: "out of time" }
... mais c'est généralement une bonne idée de les mettre dès qu'on dépasse 2~3 valeurs.
Un objet est rarement utile en dehors d'une variable, parce que si l'objet contient plusieurs valeurs on va probablement vouloir l'utiliser plusieurs fois dans le reste du code. Et puis le mettre dans une variable c'est aussi lui donner un nom et c'est toujours mieux.
Un truc sympa, est que ça à beau être un paquet de valeurs, on peut quand même le passer dans console.log()
comme n'importe quelle autre valeurs plus simple.
const user = {
name: "John Oates",
birth: 1948,
retired: false,
occupation: "out of time",
};
console.log(user);
Allez-y, essayez.
Si vous voulez lire ou changer une propriété de votre objet vous pouvez y accedez en y acollant un point .
que l'on appelle "l'opérateur d'accession" (un opérateur est juste un sybole qui combine des "opérandes". Par exemple +
est l'opérateur d'addition et prend 2 nombres en guise d'opérandes).
const user = {
name: "John Oates",
birth: 1948,
retired: false,
occupation: "out of time",
};
console.log(user.name);
user.name = "Daryl Hall";
console.log(user.name);
Ça fonctionne exactement comme les chemins de dossier et de fichiers. /documents/counter.js
veux dire "le fichier counter.js
qui est dans le dossier documents
sauf qu'on remplace les /
par des .
. user.name
étant donc la propriété name
qui est dans l'objet user
.
Et si l'analogie avec le rangement de fichiers ne vous parle pas trop, on peut constater aussi que ça se lit assez bien de droite à gauche en règle générale.
(note de traduction: Waldo = Charlie)
Les fonctions
Du code reutilisable
Si une valeur qui porte un nom est une variable alors un ensemble de quelques lignes de code qui portent un nom est une fonction.
function liftoff() {
console.log("3");
console.log("2");
console.log("1");
console.log("liftoff!!");
}
En soit ça s'écrit comme ceci. D'abord le mot function
pour déclarer que le code qui suit est une fonction. Comme let
déclare que ce qui suit est une création de variable. Ensuite le nom de la fonction (qui peut être ce que l'on veut, comme avec les variables). Puis une paire de paranthèses ()
qu'on expliquera juste après, et enfin le "corps" de la fonction (ce qu'elle fait) entre accolades {}
.
Executez le code ci-dessus pour voir.
Il ne se passe rien? Pourtant ça fait bien 5~6 lignes de code, et en plus il y à des console.log()
!
Effectivement, tout ce que ce code fait est de créer la fonction liftoff()
mais on ne s'en sert jamais.
function liftoff() {
console.log("3");
console.log("2");
console.log("1");
console.log("liftoff!!");
}
liftoff();
liftoff();
liftoff();
Pour s'en servir il suffit de taper son nom et ses parethèses comme ceci.
Exécutez le code ci-dessus.
Remarquez que la séquence de console.log()
se voit autant de fois que l'on a appelé la fonction.
Du code qui s'adapte
Donc, ces fameuses paranthèses, elles servent à quoi?
C'est ce que l'on apelle les "paramètres" de la fonction, c'est assez pratique parce que le code qui appelle la fonction peut maintenant donner des valeurs à la fonction pour qu'elle puisse travailler dessus. Sans paramètres une fonction est condamnée à faire la même chose à chaque exécution.
function twoPartLog(a, b) {
console.log("Du " + a + " et du " + b);
}
twoPartLog("jambon", "beurre");
twoPartLog("beurre", "jambon");
Donc, via ce code on créer une fonction twoPartLog()
qui demande 2 valeurs. Valeurs que l'on donne au moment où on apelle la fonction. Ce qui détermine "quelle valeur va dans quel paramètre" est leur position. La première fois qu'on apelle la fonction, elle va s'exécuter avec a
valant "jambon"
et b
valant "beurre"
tandis qu'à la deuxième exécution ce sera l'inverse a
vaudra "beurre"
et b vaudra "jambon"
.
On peut nommer les paramètres d'une fonction comme on veux, au même titre que les variables. J'aurais très bien pu utiliser first
et second
au lieux de a
et b
. C'est juste que cet example est trop petit pour être concret et c'est donc difficile de leur donner un nom pertinent.
Allez-y exécutez ce code et verifiez par vous même.
function twoPartLog(a, b) {
console.log("Du " + a + " et du " + b);
}
twoPartLog("jambon"); // "Du jambon et du undefined"
Remarquez que si on ne respecte pas une fonction en lui donnant moins que ce qu'elle doit recevoir elle s'exécute quand même en collant la valeur undefined
dans les paramètres qui n'on pas reçus de valeurs (autrement dit, ils n'ont pas été definies). Ne comptez pas là dessus c'est degoutant 🤣, considerez qui si vous ne donnez pas au fonction ce qu'elles attendent est un problème. D'ailleurs je le fait tellement jamais que je m'attendais à ce que ça crash en écrivant ce chapitre, ce qui est le cas dans tous les autres langages que je connais.
Il y a une manière plus propre de faire une fonction qui prend entre 0 et N paramètres, mais ça nous sera pas utile dans un futur proche donc on verra ça plus tard (ou pas du tout).
function twoPartLog(a, b) {
console.log("Du " + a + " et du " + b);
}
twoPartLog("jambon", "beurre", "cornichons"); // "Du jambon et du beurre"
Si vous en mettez trop ça passe aussi. Les valeurs qui sont en excédent seront recupérables avec une manip', mais pareil, evitez, c'est vraiment ouvrir la porte a des tas de bugs. La manière de faire ça proprement n'est pas utile dans l'immédiat donc on repassera.
Du code qui répond
Il est possible que l'on écrive nos fonction de telle sorte qu'elles nous rendent un résultat quand elles ont finie. Pour ca il suffit d'utiliser le terme return
et une valeur comme ceci.
function giveMeFive() {
return 5;
}
console.log(giveMeFive()); // 5
Ce qui va se passer c'est que lorsequ'on appelle une fonction on va d'abord l'exécuter puis remplacer son appel par la valeur qui aura été retournée, ce qui fait que notre exemple ci-dessus est équivalent à console.log(5)
.
Voici un exemple un peu plus concret.
function square(x) {
return x * x;
}
console.log("Le carré de 4 est " + square(4)); // Le carré de 4 est 16
Nottez aussi quelque chose d'important, return
stope l'exécution de la fonction. Donc si on rend une valeurs on quitte direcetement la fonction.
D'ailleurs on peut aussi utiliser return
sans fournir de valeur si tout ce qui nous intéresse c'est d'arreter l'exécution.
function earlyStop() {
console.log("vous me voyez");
return;
console.log("vous ne me verrez pas");
}
earlyStop();
Exécutez ce code pour vérifier que vous ne voyez pas le deuxième message.
Problème
Écrivez une fonction neg()
qui prend un nombre en paramètre et qui renvoie son opposé.
exemple d'utilisation:
console.log(neg(5)); // -5;
console.log(neg(-13)); // 13
Faire des essais dans un projet vide est une bonne idée.
Solution
function neg(x) {
return x * -1;
}
Recoller tous les morceaux
Ok, maintenant on a tout ce qu'il faut pour expliquer les éléments du chapitre précédent.
Déjà, sachez que le navigateur gère beaucoup de choses pour nous (c'est cool) donc il faut les apprendres (mais on peut le faire à notre rythme).
document
document
est une variable gérée par le navigateur qui représente notre page web. Je vous invite à exécuter console.log(document)
pour y jeter un œil, mais pas la peine d'y trainer trop longtemps parce que vous n'avez pas besoin de tout connaitre. Un petit exemple sympa et parlant c'est sa propriété title
qu'on peut donc aller chercher via document.title
.
Mais du coup maintenant vous comprennez que document.querySelector()
c'est la fonction querySelector()
de la page qui me permet de selectionner via un selecteur (CSS) et pour etre honnête c'est la seule fonction (avec document.querySelectorAll()
mais on verra plus tard) dont je me sert regulièrement dans document
.
exercice
Après avoir loggé et bien regardé document
, essayez de changer le titre de la page web via javascript. Pour rappel le titre est ce qui est contenu dans la balise <title>
en HTML et qui figure dans l'onglet du navigateur quand on visite la page avec un navigateur.
Solution
document.title = "mon super titre";
problème
En reprennant le code du compteur du chapitre précédent, faites en sorte que le titre du document soit la valeur du compteur et qu'il reste à jour lorsque le compteur change.
Solution
<script>
let count = 0;
document.title = count;
document.querySelector("#minus-button").addEventListener("click", countDown);
document.querySelector("#plus-button").addEventListener("click", handleClick);
function handleClick() {
count = count + 1;
document.title = count;
document.querySelector("#count").textContent = count;
}
function countDown() {
count = count - 1;
document.title = count;
document.querySelector("#count").textContent = count;
}
</script>
console
Eh oui, console
est aussi un objet géré par le navigateur.
Et on peut aussi y jetter un œil avec console.log(console)
.
Donc...
... tout ce qu'on fait depuis le départ c'est de grassement utilisé des choses qui sont déjà là.
console.log()
c'est juste la fonction log()
de console. document.querySelector()
c'est juste la fonction querySelector()
de la variable document
...
Element
... et d'ailleurs document.querySelector()
vous retourne un objet qui représente le premier élément HTML qui correspond. Un truc important à souligner est que tous les objets issus de document.querySelector()
ont tous la même forme, autrement dit, ils ont tous les mêmes propriétés (mais pas nécessairement les même valeurs).
Allez-y attrapez en un et loggez-le pour voir ce qu'il contient.
Et c'est tout ce qu'on à fait au chapitre précédent.
- utiliser la fonction
querySelector()
dudocument
viadocument.querySelector()
de nous rendre un élément HTML - utiliser la fonction
addEventListener()
de cet élément HTML pour lui donner une fonction à exécuter quand l'event (c'était un event de type "click") sera déclaneché
et à partir de là on à juste gardé la trace de notre progression dans une variable et mis à jour le contenu d'un élément HTML.
"C'est bien beau de regarder ce qu'il y a dans les objets comme le document ou les objets de type Element mais...
... comment je fais pour savoir qu'est-ce qui est utile?"
Quand on console.log()
quelque chose qui n'est pas à vous:
- Les noms des propriétés sont assez évocateurs ("malgré" le fait qu'ils soient en anglais)
- vous pouvez prendre votre moteur de recherche favoris et chercher "MDN <nom de la propriété>". MDN étant un site qui liste tout ce que le navigateur gère à votre place et vous propose.
C'est essentiellement pour ça que j'adore javascript, il suffit de console.log()
tout ce qui nous passe sous la main et d'aller faire de la lecture pour s'améliorer.
Mais bon, je vais aussi passer tous les prochains chapitres à vous parler de trucs très utiles qui vont pouvoir se combiner afin de produire des choses vraiment cool. Et qu'on soit clairs, le plus dur c'est le début parce que si le nombre de choses que vous connaissez est N alors le nombre de combinaisons est N*(N-1) qu'on peut simplifier N2 soit...
Les mots-clef
Les mots-clef sont des mots que l'on ne peut pas utiliser pour nommer nos fonction ou nos variables parce que javascript leur a déjà assigné un rôle.
Imaginez que j'éssaye de créer une variable qui s'appellerait let
comme ceci:
let let = 5;
En admettant que ce soit accpeté, cette ligne pourrait tenir la route mais le reste du code à partir de là deviendrait un casse-tête catastrophique parce que la machine ne saurais pas si j'éssaye d'utiliser la varibable let
ou d'utiliser le mot-clef let
pour créer une variable.
Jusqu'ici les mots-clef que nous avons vu sont:
let
const
function
return
Donc, pour récapituler:
Nottez aussi que la coloration des mots dans votre éditeur de code devrait donner une couleur différente à chacun de ces éléments.
Là où c'est possiblement difficile, c'est de faire la différence entre les variables/fonctions définies par le navigateur et les mot-clefs. Dites vous que si vous pouvez le passer dans une console.log()
ce n'est pas un mot-clef. console.log(document)
fonctionne mais console.log(let)
ou console.log(return)
est du charabia pour la machine.
if
La raison pour laquelle on cherche d'abord à déterminer si il s'agit d'un mot-clef dans le diagramme ci-dessus est d'abord parce que c'est facile vu qu'il y en a un nombre limité et que ça bouge très rarement (2~3 fois par décénnie). Mais aussi parce que certains mots-clefs on aussi des paranthèses comme if
.
if
ressemble un peu à une fonction sauf que ça s'exécute tout de suite si la condition qui est entre ses paranthèses ()
est vraie true
.
exemple simple
if (6 > 0) {
console.log("6 est positif"); // ce console.log() s'exécutera
}
if (42 > 50) {
console.log("42 est plus grand que 50"); // mais pas celui-ci
}
Symboles utiles avec le if
:
<
: plus petit que>
: plus grand que<=
: plus petit ou égal à>=
: plus grand ou égal à==
: égal à===
: strictement égal à
La différence entre ==
et ===
est que ==
sera vrai si les deux éléments comparés sont équivalents tandis qu'avec ===
le résultat sera vrai si les deux comparées ont la même valeur et le même type.
exemple
console.log(5 == 5); // true
console.log(5 == "5"); // true
console.log("5" == "5"); // true
console.log(5 === 5); // true
console.log(5 === "5"); // false
console.log("5" === "5"); // true
Nottez qu'il faut que la valeur finale entre les paranthèses du if
soit vraie, mais il n'est pas nécessaire que ce soit via une comparaison.
if(true){
console.log("je m'executerais toujours");
}
if(false){
console.log("je m'executerais jamais");
}
// donc
const maVar = true
if(maVar == true){}
// et
if(maVar){}
// sont entièrement équivalents
Aussi, si la valeur entre paranthèses n'est pas un booléen (true
ou false
) alors elle sera convertie automatiquement.
if("un peu de texte"){
console.log("je m'executerais toujours");
}
if(""){
console.log("je m'executerais jamais");
}
Les valeurs qui sont automatiquement converties en false
sont des valeurs que l'on apelle "falsy". Il en existe très peu et ceux qui vont nous intéresser sont:
- une string vide
""
undefined
0
Ce qui est pratique parce que si on veux modifier un élément HTML qui existe peut être alors on peut faire ceci
const myMain = docement.querySelector("main");
if(myMain){
myMain.textContent = "J'existe!";
}
On sélectionne l'élément <main>
et on le met dans une variable. À ce moment, la variable contient soit l'objet javascript qui représente l'élément <main>
, soit undefined
parce qu'aucun élément de la page correspondait au selecteur main
.
Un objet est equivalent a true
et undefined
est équivalent à false
, donc on rentrera dans if(myMain)
seulement si l'élément existe.
Problème
Écrivez une fonction max()
qui prend deux nombres en paramètres et qui rend le plus grand des deux.
exemple d'utilisation
console.log(max(-1, 1)); // 1
console.log(max(1238, 2)); // 1238
Solution
Vous pourriez écrire ...
function max(a, b) {
if (a > b) {
return a;
}
if (b > a) {
return b;
}
}
... mais si on se rapelle que return
arrête la fonction on peu simplifier comme ceci
function max(a, b) {
if (a > b) {
// a est plus grand que b?
return a; // oui? tient prend a
}
return b; // on ne t'as pas donné a? donc prend b.
}
Problème
Reprennez le code du compteur au chapitre d'avant et ne laissez pas l'utilisateur descendre en dessous de 0 ni aller au dessus de 10.
indice
Au moment de changer le compteur vous pouver toujours tester la valeur du compteur et si elle dépasse dans un sens ou dans l'autre, vous la ramenez à la bonne valeur.
Solution
<script>
let count = 0;
document.querySelector("#minus-button").addEventListener("click", countDown);
document.querySelector("#plus-button").addEventListener("click", handleClick);
function handleClick() {
count = count + 1;
// ça depasse? oui?
if (count > 10) {
count = 10; // ça depasse plus
}
document.querySelector("#count").textContent = count;
}
function countDown() {
count = count - 1;
// ça depasse? oui?
if (count < 0) {
count = 0; // ça depasse plus
}
document.querySelector("#count").textContent = count;
}
</script>
Altenativement:
<script>
let count = 0;
document.querySelector("#minus-button").addEventListener("click", countDown);
document.querySelector("#plus-button").addEventListener("click", handleClick);
function handleClick() {
// est-ce que je suis encore en dessous du maximum?
// oui? donc je peux me permettre de mettre à jour
if (count < 10) {
count = count + 1;
document.querySelector("#count").textContent = count;
}
}
function countDown() {
// est-ce que je suis encore au desssus du minimum?
// oui? donc je peux me permettre de mettre à jour
if (count > 0) {
count = count - 1;
document.querySelector("#count").textContent = count;
}
}
</script>
else
Le mot-clef else
permet de mettre un bloc après le bloc du if
qui s'exécutera si la condition du if
est fausse.
if(true){
console.log("je m'executerais toujours");
}else{
console.log("je m'executerais jamais");
}
if(false){
console.log("je m'executerais jamais");
}else{
console.log("je m'executerais toujours");
}