
La POO en JavaScript
Semblable à Java⊠en plus souple.
Créer des objets
Un objet est dĂ©clarĂ© avec des accolades, Ă lâintĂ©rieur desquelles on dĂ©clare une liste de propriĂ©tĂ©s qui sont des paires nom:valeur.
On accÚde à la clé avec le point (BP) ou les crochets.
Les objets sont dynamiques : pas de new, ajout de propriĂ©tĂ©s simplifiĂ© â> cela demande une certaine rigueur pour ne pas faire nâimporte quoi !
let uneFleur = {nom:"tulipe", couleur:"jaune"};
console.log(uneFleur); //{ nom: 'tulipe', couleur: 'jaune' }
console.log(uneFleur.nom + " === " + uneFleur["nom"]); //tulipe === tulipe
uneFleur.couleur="orange"; //orange
console.log(uneFleur.couleur);Il est possible de faire des tableaux dâobjets, mĂȘme des tableaux de tableaux dâobjetsâŠ
â> notation JSON.
Créer des classes
1. façon traditionnelle
Une classe se déclare avec let (comme une variable) et le mot-clé function : elle prend entre zéro et plusieurs paramÚtres, des attributs et des éventuelles fonctions.
Une instance se crée avec le mot-clé new et en renseignant les valeurs des différents paramÚtres.
let UneClasseALancienne = function (unParam, autreParam) {
this.unParam = unParam;
this.autreParam = autreParam;
this.uneFonction = function () {
console.log("Je suis une fonction de classe.");
}
}
let uneInstance = new UneClasseALancienne("une chaine de caractĂšres", 42);
console.log(uneInstance);
/*
UneClasseALancienne {
unParam: 'une chaine de caractĂšres',
autreParam: 42,
uneFonction: [Function (anonymous)]
}
*/
console.log(uneInstance.uneFonction()); //Je suis une fonction de classe.
2. Nouvelle façon (TypeScript)
Une classe se déclare avec le mot-clé class, elle possÚde un constructeur auquel on passe des paramÚtres et au sein duquel on déclare les attributs, elle possÚde également des méthodes.
Comme en Java, mais simplifié⊠On passe en fait par le tsc, compiler du TypeScript.
class UneClasse {
constructor(unParam, autreParam) {
this.unParam = unParam;
this.autreParam = autreParam;
}
uneFonction() {
console.log("Je suis une fonction de classe.");
}
}
let uneNouvelleInstance = new UneClasse("une chaine de caractĂšres", 42);
console.log(uneNouvelleInstance); //UneClasse { unParam: 'une chaine de caractĂšres', autreParam: 42 }
console.log(uneNouvelleInstance.uneFonction()); //Je suis une fonction de classe.
Héritage
Une classe hérite des attributs et méthodes du parent.
- Ă lâancienne, le lien Ă la classe parent se fait explicitement lors de la dĂ©claration de la classe enfant avec
ClasseParent.call(this, params parent);
- avec la nouvelle maniĂšre, le lien Ă la classe parent se fait avec
extendslors de la déclaration de la classe enfant et on utilisesuper(params parent);dans le constructeur enfant pour faire appel au constructeur parent
BP : prĂ©fĂ©rer lâutilisation declassetextends.
(+) Notion de prototype
Notion qui me reste hermétique⊠et qui est désuÚte.
Un prototype est la structure || forme que doit respecter la classe enfant et permet lâhĂ©ritage des fonctions parent avec ClasseEnfant.prototype = Object.create(ClasseParent.prototype);.
Il est ensuite possible de substituer les fonctions avec ClasseEnfant.prototype.fonctionASubstituer = ...
Librairies
Un fichier JavaScript peut ĂȘtre considĂ©rĂ© comme une libraire (ex : jQuery).
Contexte dâexĂ©cution
Quand on a diffĂ©rentes librairies, on veut avoir des contextes (ou cadres) dâexĂ©cution.
On utilise des fonctions anonymes, déclarées avec let uneFonctionAnonyme = function(params) { instructions } et appelées simplement avec uneFonctionAnonyme(valeurs);.
Une autre façon de dĂ©clarer une fonction anonyme est dâenlever le let et de lâencapsuler entre parenthĂšses : (function(param) { instructions }) ();.
BP : câest mieux dâencapsuler la fonction anonyme car elle nâest pas enregistrĂ©e (elle nâa pas de nom), ce qui permet un gain de performance.
Il est possible de les déclarer et de les appeler immédiatement : fonctions anonymes immédiatement invoquées. La fonction est encapsulée dans des parenthÚses, on renseigne la valeur des paramÚtres juste aprÚs : (function(param) { instructions }) (valeurs);
On utilise Ă©galement des fonctions flĂ©chĂ©es qui diffĂšrent des fonctions anonymes car elles nâutilisent pas le mot-clĂ© function. Il sâagit dâune simplification de la syntaxe de dĂ©claration dans laquelle les paramĂštres sont entre parenthĂšses (qui restent vides sâil nây a pas de paramĂštres), suivis dâune flĂšche => et des instructions entre accolades. Lors de lâappel, les instructions sont Ă©valuĂ©es et le rĂ©sultat est retournĂ© : let uneFonctionFlechee = () => { instructions };.
En Java, cela équivaut aux fonctions lambda.
let fonctionAnonyme = function(param) {
console.log("Je suis une fonction anonyme !");
}
let fonctionInvoquee = (
function(param) {
console.log("Je suis immédiatement invoquée !");
})("un paramĂštre");
(() => {
console.log("Je suis aussi une fonction invoquée, mais fléchée !");
})();(+) Notion de closure
DĂ©suetâŠ
Spécialisation de méthodes :
via prototype possible mais verbeux et statique
via une fonction contextualisée (une closure) qui permet de retourner une fonction encapsulée (protégée du code)
exemple avec un compteur : on utilise une fonction anonyme automatiquement invoquĂ©e qui let un compteur et qui retourne une fonction anonyme dans laquelle jâincrĂ©mente le compteur et retourne le compter
â> donc le let est immĂ©diatement invoquĂ© lorsque le script est interprĂ©tĂ© (quand il passe sur la ligne) et ensuite quand on appelle la fonction, y a que le return qui est exĂ©cutĂ© (ça incrĂ©mente le compteur et il est hors de portĂ©e si on passe par la fonction)
(+) pattern factory par closure
Stockage local
Deux variables sont disponibles pour sauvegarder des choses dans le navigateur, qui disparaissent lorsque le cache est supprimé : LocalStorage et SessionStorage, avec des méthodes associées comme setItem(cle,valeur), geItem(cle), removeItem(cle), clear().
object = { name: "Bob", age: 42 };
// sauvegarder un tableau, prealablement transforme en string
localStorage.setItem("oneObject", JSON.stringify(object));
// recuperer ce tableau
object = JSON.parse(localStorage.getItem("key"));
console.log(object);JSON.stringify() permet de transformer un objet JSON en string. Lâinverse se fait avec la mĂ©thode JSON.parse().
â> Souvent utilisĂ© pour les Ă©changes de donnĂ©es depuis et vers un serveur web, puisquâil faut que la donnĂ©e soit une string pour ĂȘtre envoyĂ©e Ă un serveur web.
Traitements asynchrones
On parle de âsynchroneâ lorsque les traitements sont effectuĂ©s les uns aprĂšs les autres et dââasynchroneâ lorsquâils sont effectuĂ©s en parallĂšle.
Les traitements asynchrones permettent de laisser des traitements un peu longs se faire et récupérer le résultat plus tard, ce qui donne des applications plus réactives.
Option 1 : les callbacks
DĂ©suet⊠RĂ©volution Ă lâĂ©poque, maintenant on utilise des observables et des promesses.
âCapacitĂ© de passer une fonction Ă une autre fonction et sâassurer que cette fonction peut ĂȘtre appelĂ©e dans notre fonctionâ.
Le mot-clĂ© callback est passĂ© en paramĂštre dâune fonction A lors de sa dĂ©claration. Lors de lâappel de cette fonction A, une fonction B est passĂ©e pour le paramĂštre callback.
Exemple dâutilisation : mettre Ă jour une information sur un site (nombre de visiteurs, compteursâŠ) grĂące aux mĂ©thodes setTimeout() ou setInterval() utilisĂ©es comme callbacks.
// Exemple d'Alain Cariou
// les méthodes direHello() et direHaha() sont passés en tant que callback
// à la méthode repeter
function direHello() {
console.log("Hello World !");
}
function direHaha() {
console.log("Haha !")
}
function repeter(callback) {
setInterval(function() {
callback()
}, 1000);
}
repeter(direHello);
console.log("AprÚs répéter");
repeter(direHaha);Option 2 : les promesses (trĂšs actuel)
âMĂ©canisme qui permet de faire un traitement de maniĂšre asynchroneâ.
Il fonctionne avec un objet Promise qui prend en paramĂštre une fonction, qui elle-mĂȘme prends deux paramĂštres (resolve si la promesse est un succĂšs et reject en cas dâerreur).
Pour lâexĂ©cuter, on lâappelle et on rĂ©cupĂšre le rĂ©sultat avec .then. On peut utiliser un . catch.
Exemple de traitement : interroger une API.
// Exemple d'Alain Cariou
function getData() {
return new Promise((resolve, reject) => {
console.log("Début promesse !");
resolve({"ok": "Tout s'est bien passé !"});
// setTimeout(() => {
// resolve({"ok": "Tout s'est bien passé !"});
// reject(new Error("Echec de la promesse !"));
// }, 2000);
});
}
let result;
console.log("I - Je fais des trucs.");
getData().then((data) => {
result = data;
console.log("II - Récupération des données : " + data);
}).catch((error) => {
console.log(error);
});
result = getData();
console.log("III - Je fais d'autres trucs !");
console.log(result);
(+) les observables
Hors programme.
On peut chaĂźner les uns aux autres, on sây subscribe (le flux de donnĂ©es peut continuer Ă arriver) â promesse qui est juste une action qui commence et se termine.