BASES
VARIABLES ET CONSTANTES
-Une variable s'initialise avec: let
-Une constante, donc non modifiable, avec: const
-Elles ont six types primitifs principaux:
- Number: qui peuvent être positifs, négatifs, décimaux
- String: chaîne de caractère à mettre entre quotes
- Boolean: pour true ou false
- null
- undefined
- symbol
-Pour vérifier un type, utiliser: console.log(typeof leNomDeLaVariable);
-La concaténation se fait avec +
ex: let wholeName = firstName + ' ' + lastName;
OBJET
-Les objets JavaScript sont écrits en JSON (JavaScript Object Notation). Ce sont des séries de paires clés/valeurs qui peuvent être de types différents.
Un objet est dit pour cette raison de type complexe. C'est aussi un type référence.
let episode ={
title: "La guerre des étoiles",
duration: 45,
hasBeenWached: true
};
-Accéder aux données:
let titreEpisode = episode.title;
console.log(titreEpisode);
CLASSES
-Une classe permet de construire plusieurs mêmes objets, appelés instances de la même classe. Une classe est aussi un type complexe.
-Le constructor d'une classe est la fonction qui est appelée quand on crée une nouvelle instance.
-This fait référence à la nouvelle instance. La notation dot -le point- est donc utilisée pour attribuer les valeurs reçues aux clés correspondantes.
class Book {
constructor(title, author, pages) {
this.title = title;
this.author = author;
this.pages = pages;
}
}
Créer des instances avec le mot clé new:
let myBook = new Book("L'Histoire de Tao", "Will Alexander", 250);
ARRAY
-Il est possible d'insérer des données, des variables, des objets et des arrays dans un array.
Comme les objets, un tableau est de type référence.
Un array récupère des données de manière différente en fonction des types.
-Si l'on récupère des données d'objets ou de tableaux, il prendra les références qui y sont attribuées.
-Si l'on récupère des variables il ne sera pas possible de changer leur résultat en créant d'autres variables car se sont les valeurs qui auront été prise.
Syntaxe:
let guests = [firstGuest, secondGuest, thirdGuest];
Quelques fonctions:
let values =
guests.
length;
Donnera le nombre d'éléments contenus dans l'array
guests.
push("fourthGuest");
Ajoute "fourthGuest" à la fin du tableau
guests.
unshift("fifthGuest");
Ajoute "fifthGuest" au début du tableau
guests.
pop();
Supprime le dernier élément du tableau
CONDITIONS - OPERATEURS
-Comme avec de nombreux languages, il est possible d'utiliser les conditions if, else if, else, et les opérateurs + - * /, les expressions de comparaion < <= => > = == === != !== !=== et les opérateurs logiques && || !
SCOPE
Les variables créées par let ou const ne peuvent être vues ou utilisées qu'à l'intérieur du bloc de code dans lequel elles sont déclarées.
Pour récupérer une valeur, il faut déclarer la variable en dehors du bloc
Ce phénomène est appelé scope de bloc, ou block scope
Un bloc de code, aussi souvent appelé bloc tout court, est une section de code incluse entre accolades {}.
let userLoggedIn
= true;
if (userLoggedIn) {
let welcomeMessage = 'Welcome back!';
} else {
let welcomeMessage = 'Welcome new user!';
}
console.log(welcomeMessage);
//Ce code renvoie une erreur
Pour récupérer la valeur de welcomeMessage, il faut donc déclarer la variable en dehors du bloc:
let userLoggedIn
= true;
let welcomeMessage
= '';
let welcomeMessage = 'Welcome back!';
} else {
let welcomeMessage = 'Welcome new user!';
}
console.log(welcomeMessage);
//Ce code renvoie Welcome back!
Autre exemple avec switch. Le code sera disponible à l'interieur, mais pas dans le code environnant
switch (firstUser.accountLevel) {
case 'normal':
// attention ici, il s'aggit de : et non d'un point virgule
console.log('You have a normal account!');
break;
case 'premium':
console.log('You have a premium account!');
break;
case 'mega-premium':
console.log('You have a mega premium account!');
break;
default:
console.log('Unknown account type!');
}
BOUCLES FOR
Prenons le tableau suivant:
const passengers = [
"Will Alexander",
"Sarah Kate'",
"Audrey Simon",
"Tao Perkington"
]
for (
let i
= 0; i
< passengers.
length; i
++) {
console.log("Passager embarqué !");
}
La fonction
length permet de parcourir un
tableau dans son ensemble.
Il y a deux façons plus simples de parcourir des tableaux ou de faire une itération sur leurs éléments.
La boucle for in:
for (
let i
in passengers) {
console.log("Embarquement du passager " + passengers[i]);
}
La boucle for of:
for (
let passenger
of passengers) {
console.log("Embarquement du passager " + passengers);
}
Ceci atteint le même résultat, mais il n'y a pas à s'inquiéter des indices du tableau.
C'est encore plus utile si le tableau est plus complexe et contient par exemple des objets :
const passengers = [
{
name: "Will Alexander",
ticketNumber: 209542
},
{
name: "Sarah Kate",
ticketNumber: 169336
},
{
name: "Audrey Simon",
ticketNumber: 779042
},
{
name: "Tao Perkington",
ticketNumber: 703911
}
]
for (
let passenger
of passengers) {
console.log('Embarquement du passager ' + passenger.name + ' avec le ticket numéro ' + passenger.ticketNumber);
}
BOUCLES WHILE
Une boucle while vérifie si une condition est vraie. Si c'est le cas, la boucle se poursuit, sinon elle s'arrête.
let seatsLeft
= 10;
let passengersStillToBoard
= 8;
let passengersBoarded
= 0;
while (seatsLeft
> 0
&& passengersStillToBoard
> 0) {
passengersBoarded++; // un passager embarque
passengersStillToBoard--; // donc il y a un passager de moins à embarquer
seatsLeft--; // et un siège de moins
}
console.log(passengersBoarded);
// imprime 8, car il y a 8 passagers pour 10 sièges
ERREURS D'EXECUTION
Souvent associé aux ressources extérieures (connexions réseau, appareils physiques, etc.) ou à une saisie/erreur humaine.
Dans certains cas prévisibles il est possible de les prévenir afin de ne pas faire planter le programme avec :
-if / else pour vérifier la validité des données:
if (dataExists
&& dataIsValid) {
// utiliser les données ici
}
else {
// gérer l'erreur ici
}
-try / catch
try {
// code susceptible à l'erreur ici
}
catch (error) {
// réaction aux erreurs ici
}
finally {
//code à executer
}
FUNCTION
Syntaxe:
function nameFunctionReturnResultAdd(parametreNumUn, parametreNumDeux) {
return parametreNumUn + parametreNumDeux
}
Nouvelle syntaxe:
const add
= (firstNumber, secondNumber)
=> {
const result = firstNumber + secondNumber;
return result;
//ou simplement
return firstNumber + secondNumber;
}
const resultat = add(4, 3);
console.log(resultat);
//S'il n'est pas nécessaire de stocker le résultat dans une constante ou variable:
console.log(add(5, 4));
-Il est aussi possible de passer des tableaux ou des objets en argument.
Exemple pour une moyenne dont les notes seraient dans un tableau:
const calculateAverageRating = (ratings) => {
if(ratings.
length === 0) {
return 0;
}
let sum
= 0;
for (
let rating
of ratings) {
sum += rating;
}
return sum / ratings.length;
}
const tauRatings = [5, 4, 5, 5, 1, 2];
const colinRatings = [5, 5, 5, 4, 5];
const tauAverage =
calculateAverageRating(tauRatings);
const colinAverage =
calculateAverageRating(colinRatings);
Passer un objet ou un tableau à une fonction revient ici aussi à lui passer la référence. C'est important lors de l'envoi d'un objet en retour.
FONCTION DE FONCTIONS
Il est important qu'une fonction soit le plus court possible, avec des noms très explicite pour une meilleur compréhension.
Il est préférable d'écrire plusieurs petites fonctions même si elles vont ensemble et de les regrouper ensuite.
Exemple:
const getWordCount = (stringToTest)
=> {
const wordArray = stringToTest.split(' ');
return wordArray.length;
}
const getLetterCount = (stringToTest)
=> {
const wordArray
= stringToTest.
split(' ');
let totalLetters
= 0;
for (
let word
of wordArray) {
// retire la ponctuation pour ne compter que les lettres
word.replace(/[.,\/#!$%\^&\*;:{}=\-_`~()]/g, "");
totalLetters += word.length;
}
return totalLetters;
}
/*
renvoie la longueur moyenne des mots
arrondie à deux chiffres après la virgule
*/
const getAverageWordLength = (stringToTest)
=> {
return parseFloat((getLetterCount(stringToTest) / getWordCount(stringToTest)).toFixed(2));
}
const printStringStats = (stringToTest)
=> {
console.log({
wordCount: getWordCount(stringToTest),
letterCount: getLetterCount(stringToTest),
averageWordLength: getAverageWordLength(stringToTest)
})
}
console.log(getLetterCount('importe'));
printStringStats('upload');
METHODES D'INSTANCE - DE CHAMPS
Méthode instance:
Une méthode d'instance est une fonction faisant partie d'une classe, et qui agit sur une instance de cette classe.
-Exemple:
class BankAccount {
//class compte en banque
constructor(owner, balance) {
//propriétaire, solde
this.owner = owner;
this.balance = balance;
}
showBalance() {
// Méthode(qui est en fait une fonction)
console.log("Solde: " + this.balance + " EUR"); //Appel de this pour pouvoir accéder à la valeur des instances
}
}
const newAccount = new BankAccount("Will Alexander", 500);
newAccount.showBalance(); // Appel de l'instance newAccount et de la méthode showBalance
Il est possible aussi d'ajouter des méthodes capables de modifier les propriétés de l'instance.
Dans le corps d'une classe, le mot clé this fait référence à l'instance créée de la classe. Dans cet exemple, il fait référence à newAccount.
class BankAccount {
//class compte en banque
constructor(owner, balance) {
//propriétaire, solde
this.owner = owner;
this.balance = balance;
}
showBalance() {
// Méthode pour afficher le solde
console.log("Solde: " + this.balance + " EUR"); //Appel de this pour pouvoir accéder à la valeur des instances
}
deposit(amount) {
//Méthode pour déposer de l'argent
console.log("Dépôt de " + amount + " EUR");
this.balance += amount; // additionne le dépot au solde avec this
this.showBalance(); // retourne le nouveau solde
}
withdraw(amount) {
//Méthode pour retirer de l'argent
if (amount
> this.balance) {
console.log("Retrait refusé !");
}
else {
console.log("Retrait de " + amount + " EUR");
this.balance -= amount; // retire le montant du solde avec this
this.showBalance(); // retourne le nouveau solde
}
}
}
const newAccount = new BankAccount("Will Alexander", 500);
newAccount.showBalance(); // Appel de l'instance newAccount et de la méthode showBalance
newAccount.deposit(50);// Appel de l'instance newAccount et de la méthode deposit
newAccount.withdraw(100);// Appel de l'instance newAccount et de la méthode withdraw
-Exemple avec un tableau
ICI
Méthode statique:
class BePolite {
static sayHello() {
console.log("Hello!");
}
static sayHelloTo(name) {
console.log("Hello " + name + "!");
}
static add(firstNumber, secondNumber) {
return firstNumber + secondNumber;
}
}
BePolite.sayHello(); // imprime "Hello!"
BePolite.sayHelloTo("Will"); // imprime "Hello Will!"
const sum = BePolite.add(2, 3); // sum = 5
Toutes ces fonctionnalités pourraient être des fonctions, mais l'avantage d'utiliser des méthodes de classes statiques est par exemple de pouvoir faire un regroupement par catégorie ou par type.
Il existe déjà certaines méthodes auxquelles on peut aussi faire appel, comme la méthode math par exemple:
const randomNumber = Math.random(); // crée un nombre aléatoire sur l'intervalle [0, 1]
const roundMeDown = Math.floor(495.966); // arrondit vers le bas à l'entier le plus proche, renvoie 495
TESTS
Il y a trois types de tests :
- Les tests unitaires
- Les tests d'intégration
- Les tests fonctionnels (E2E)
Bien que des tests manuels sur du code peuvent fonctionner, il existe des architectures automatisées qui rendent plus faciles et fiables les tests.
Plus d'explications
ICI
RECURSIVITE
Une fonction récursive est une fonction qui s'appelle elle-même. Elle permet de diviser le temps de recherche.
Imaginons un tableau, plutôt que de parcourir tout le tableau, on le "scinde en deux", puis, l'on va chercher du côté où se trouve ce que nous recherchons, et l'opération va se répéter jusqu'à trouver une réponse, ou s'arrêter s'il ne trouve rien.
const binarySearch = (array, thingToFind, start, end) => {
if (start
> end) {
//A la fin de son parcours, start, finit par être supperieur à end si la valeur recherchée n'est pas dans le tableau. Il est important de stopper le processus de recherche ainsi, sans quoi le programme pourrait continuer en boucle
return false;
}
let middle
= Math.floor((start
+ end)
/ 2);
if (array[middle]
=== thingToFind) {
return true;
}
if (thingToFind
< array[middle]) {
return binarySearch(array, thingToFind, start, middle - 1);
}
else {
return binarySearch(array, thingToFind, middle + 1, end);
}
}
L'OBJET WINDOW
L'objet window donne accès à tout ce qui se trouve dans notre page.
Avec console.log(window), la liste de tout ce que l'on code s'affiche, ainsi que tout ce qu'il y a par défaut.
L'OBJET LOCATION
L'objet location est une propriété de l'objet global window.
window.location="href..." renverra vers la page souaitée.
Voir les détails en tapant console.log(window.location).
DOM
Les éléments du DOM sont des objets JavaScript et il existe différentes façons de retrouver des éléments dans notre page.
Tout commence avec le document. Cet objet, est le point de départ du DOM. Il représente votre page entière.
C'est donc lui qui contient les fonctions dont vous aurez besoin pour retrouver les éléments que vous cherchez.
Astuce pour voir les propriétés d'un élément quand celle ci ne sont pas affichées:
console.log(cible.parentElement.children); .
ACCEDER AUX ÉLÉMENTS DU DOM
HIÉRARCHIE:
- console.log(document) donne accès à tous les éléments du DOM.
- console.log(document.title) donne accès au contenu de la balise title, qu'il est possible de modifier ainsi:
document.title = "New title".
- console.log(document.body.children) donne accès aux enfants da la balise body sous forme d'un tableau, ou plutôt d'une "collection HTML".
- Si l'on veut accéder à l'un d'entre eux en particulier, il suffit de le préciser entre crochet console.log(document.body.children[0])
- Il est également possible de continuer afin d'accéder à l'élément souhaité console.log(document.body.children[0].children.children)...
- Accéder au premier élément: firstElementChild console.log(document.body.firstElementChild).
- Accéder au dernier élément: lastElementChild console.log(document.body.lastElementChild).
- Accéder à un élément frère: nextElementSibling console.log(document.body.children[0].nextElementSibling).
- Accéder à un élément parent: parentElement console.log(document.body.children[0].parentElement).
RÉCUPÉRER ET MODIFIER UN ÉLÉMENT:
- Modifier du texte avec textContent: document.body.children[0].textContent = "JAVA" .
MODIFIER LE STYLE:
- Modifier le style avec les objets style et (par exemple) backgroundColor (en camelcase): document.body.children[0].style.backgroundColor = "blue" .
ACCÉDER/MODIFIER UNE CLASS:
- Accéder aux class avec classList: console.log(document.body.children[0].classList) .
- Ajouter une class avec classList.add: document.body.children[0].classList.add("newClass") .
- Supprimer une class avec classList.remove: document.body.children[0].classList.remove("nameClass") .
BASCULER:
- Basuler, enlever un élément s'il y est ou l'ajouter s'il n'y est pas avec toogle: document.body.children[0].classList.toogle("nameClass") .
ACCÉDER/MODIFIER LES ATTRIBUTS(src, rel, href...):
- Accéder à un attribut avec getAttribute pour récupérer son contenu: console.log(document.body.children[0].getAttribute("src")) .
- Modifier un attribut avec setAttribute: document.body.children[0].setAttribute("src", "./cheminImage.png") .
SÉLÉCTIONNER UN ÉLÉMENT:
- Accéder à un élément en ciblant un id avec getElementById(ici element sans s): console.log(document.getElementById("nameId")) .
- Modifier le contenu : document.getElementById("nameId").textContent = "new contenu" .
Dans les deux exemples suivant, elements s'ecrit avec un s. Le résultat sera retourné sous forme de "tableau"(HTML collection). On peut donc séléctionner un élément en particulier en le ciblant entre crochet
- Accéder à un élément en ciblant une balise HTML avec getElementsByTagName: console.log(document.getElementByTagName("div ou autre")) .
- Accéder à un élément en ciblant une class avec getElementsByClassName: console.log(document.getElementsByClassName("className")) .
- Il est bien sûr possible de stocker le résultat dans une variable:
const maVar = document.getElementsByClassName("className")[0] .
- Séléctionner un élément avec querySelector ou querySelectorAll:
- querySelector renvoit le premier élément qu'il trouve: console.log(document.querySelector(".className ou div ou..."))
- querySelectorAll envoit tous les résultats, sous forme de "tableau" (NodeList): console.log(document.querySelectorAll(".className ou div ou...."))
MODIFIER L'ORDRE DES ÉLÉMENTS:
Imaginons 3 div directement dans le body avec chacune un background différent et donc une class différente ayant le nom de leurs couleur.
- création de trois variable ciblant chacune un élément:
- const rouge = document.querySelector(".rouge");
- const vert = document.querySelector(".vert");
- const bleu = document.querySelector(".bleu");
- document.body.insertBefore(bleu, vert);
-insertBefore va placer la div avec la class bleu avant la div avec la class verte.
-rouge.appendChild(bleu);
- On cible le contenu de la cont rouge(donc la div qui contient la class rouge), puis on lui ajoute le contenu de la const bleu(donc la div qui a la class bleu).
- La div bleu se trouve maintenant dans la div rouge.
- document.body.replaceChild(bleu, rouge);
-replaceChild va remplacer la div avec la class rouge par la div avec la class bleu.
- bleu.parentElement.removeChild(bleu);
- RemoveChild va supprimer l'ENFANT. Si l'on cible la const bleu comme point de départ, il faut donc remonter à l'élément parent(parentElement), puis supprimer l'enfant(bleu).
- rouge.remove();
- Remove va supprimer la div rouge mais cela ne fonctionne pas sur tout les navigateurs.
CRÉER DES ÉLÉMENTS:
Quelques exemples:
const jaune = document.createElement("div");
jaune.classList.add("jaune");
jaune.textContent = "jaune";
document.body.appendChild(jaune);
function planifierTache(heure, tache){
const newTache = document.createElement("li");
newTache.innerHTML = `< h3>${heure}< / h3>< p>${tache}< / p>`;
document.querySelector("ul").appendChild(newTache);
}
planifierTache("3h00", "dormir");
innerHTML sert à placer du code HTML, ici, à l'interieur du li.
LES ÉVÈNEMENTS
Chaque évènement contient plusieurs types
Voir
EXECUTER DU CODE EN RÉACTION A UN ÉVÈNEMENT
Avec Event Handler(gestionnaire d'évènement)
Se sont des propriétés qui commence toujours par on
Liste de tout les gestionnaires d'évènements dans la liste à gauche, dans
propriétés ici
Dans l'exemple ci-dessous, onload permettra d'executer le code lorsque la page aura finit de charger.
A noter que le code affécté doit être placé dans une fonction:
window.
onload = function(){
const rouge = document.querySelector(".rouge");
const vert = document.querySelector(".vert");
const bleu = document.querySelector(".bleu");
//
onclick permet d'effectuer des actions après un clic
//Si l'on crée plusieurs actions, comme plus bas, ce sera la dernière qui sera executée car onclick ne permet pas plusieurs actions.
//Si l'on met un argument, il fera référence aux paramètres de mouseEvent
rouge.onclick =
function(){
rouge.textContent = "Rouge cliqué !";
}
rouge.onclick =
function(){
bleu.textContent = "Rouge cliqué 2 !";
}
}
Avec Event Listener(écouteur d'évènement)
Une autre manière d'executer du code lors d'un évènement est d'utiliser la fonction addEventListener qui prendra deux paramètre: l'évènement et la function à executer quand se produit cet évènement.
Avantages:
- Permet d'ajouter plusieurs gestionnaires pour un évènement. Utile pour les bibliothèques AJAX, modules JavaScript ou code qui a besoin de fonctionner correctement avec d'autres bibliothèques/extensions.
- Contrôle plus fin sur la phase d'activation de l'écouteur(capture contre propagation)
- Fonctionne avec tout éléments du DOM, pas que les éléments HTML.
Exemple:
window.onload = function(){
const rougeAdd = document.querySelector(".rouge_add_listener");
const vertAdd = document.querySelector(".vert_add_listener");
const bleuAdd = document.querySelector(".bleu_add_listener");
rougeAdd.addEventListener("click", function(){
rougeAdd.textContent = "Rouge cliqué !";
});
rougeAdd.addEventListener("click", function(){
bleuAdd.textContent = "Rouge cliqué 2 !";
});
}
PROPAGATION DES ÉVÈNEMENTS
S'il on a deux div comme ceci:
window.onload = function(){
const parent = document.querySelector("#parent");
const enfant = document.querySelector("#enfant");
enfant.addEventListener("click", enfantFunction);
parent.addEventListener("click", parentFunction);
function enfantFunction(event){
console.log("clic sur enfant");
}
function parentFunction(event){
console.log("clic sur parent");
}
}
Si l'on clic sur le parent, dans la console, on aura "clic sur parent".
Si l'on clic sur la div enfant, la console affichera "clic sur enfant" puis "clic sur parent".
Il débute des enfants et remonte vers les parents s'ils contiennent eux aussi un addEventListener.
C'est ce que l'on appele le bouillonnement ou event bubbling en anglais.
Cette phase vient après la phase de capture, qui elle, suis le sens inverse.
Si l'on veut executer le code pendant la phase de capture, il suffit d'ajouter true, en troisième paramètre.
PROPRIÉTÉS DE BASE DE L'OBJET EVENT
Voir la liste à gauche dans propriétés
Ici
Quelques exemples(avec une de nos fonction vu plus haut):
function parentFunction(event){
console.log(event.type); //Donne le type, ici: click
console.log(event.target); //Donne l'élément sur qui a débuté l'évènement, ici, la div qui contient l'id="parent" si l'on clic sur le parent et la div qui contient l'id enfant si l'on clic sur l'enfant
console.log(event.currentTarget); //Donne la target du moment où on execute le code. Le point de départ
}
MÉTHODES DE BASE DE L'OBJET EVENT
Voir la liste à gauche dans méthodes
Ici
Quelques exemples:
function enfantFunction(event){
event.stopPropagation(); //Stoppera la propagation. Si l'on clic sur bleu, il n'y aura pas le résultat de la div parent
}
Méthode preventDefault():
const form = document.querySelector("form");
form.addEventListener("submit", envoyerForm);
function envoyerForm(event){
event.preventDefault(); //prevent default empêcher l'action par défaut. Ici, le rechargement de page.
console.log("Formulaire envoyé !");
}
REQUETES HTTP - AJAX