javascript tome iii - classes

Transcription

javascript tome iii - classes
Les CLASSES
J AVA S C R I P T (Programmation Internet) V O L . I I I
Pour Débutants
J.B. Dadet DIASOLUKA Luyalu Nzoyifuanga
+243 - 851278216 - 899508675 - 991239212 - 902263541 - 813572818
La dernière révision de ce texte est disponible sur CD.
Les « CLASSES » en JavaScript :
Un [pseudo] type particulier en JavaScript, c’est la « class » (à ne pas
confondre avec l’attribut « class » des balises HTML).
Les « classes » permettent et facilitent l’usage de « méthodes statiques ».
<script type="text/javascript"> "use strict";
class O {
static auj() {return Date()};
}
let i = new O();
console.log("O.auj = ",O.auj());
// console.log("i.auj = ",i.auj());
// TypeError: i.auj is not a function
</script>
Une autre illustration avec le pseudo-type « class » :
<script type="text/javascript"> "use strict";
class Quad {
static quad(n) {
n = n || 1;
// Si n== 0 ou indéfini, alors = 1.
Les CLASSES en JavaScript
return n * 4;
}
}
// A accès à (ou extension de) Quad ci-haut
class DbleQuad extends Quad {
static quad(n) {
return super.quad(n) * super.quad(n);
// Le quad de Quad ci-haut, pas
// celui juste ci-dessus.
}
}
console.log(Quad.quad());
console.log(Quad.quad(5));
// quad() de la class Quad
// 4
// 20
console.log(DbleQuad.quad(3));
// quad() de la classe DbleQuad
</script>
// 144
CHAPITRE 6 : Quelques notions importantes à savoir :
I. Classes en JavaScript :
Contrairement aux langages C/C++, JS ne possède pas les types de données enum, structure...., et même les objets en JS ne sont pas des
classes comme dans C++. https://www.ecma-international.org/ecma-262/5.1
ECMAScript is object-based: basic language and host facilities are provided by objects,
and an ECMAScript program is a cluster of communicating objects. An ECMAScript
object is a collection of properties each with zero or more attributes that determine
how each property can be used—for example, when the Writable attribute for a property is set to false, any attempt by executed ECMAScript code to change the value of the
property fails. Properties are containers that hold other objects, primitive values, or
functions. A primitive value is a member of one of the following built-in types: Undefined, Null, Boolean, Number, and String; an object is a member of the remaining
built-in type Object; and a function is a callable object. A function that is associated
with an object via a property is a method.
J.D.B. DIASOLUKA Nz. Luyalu
2 / 25
JavaScript Tome-III
Les CLASSES en JavaScript
ECMAScript defines a collection of built-in objects that round out the definition of
ECMAScript entities. These built-in objects include the global object, the Object object, the Function object, the Array object, the String object, the Boolean object, the
Number object, the Math object, the Date object, the RegExp object, the JSON object, and the Error objects Error, EvalError, RangeError, ReferenceError, SyntaxError, TypeError and URIError.
JS est un langage de programmation orienté objet (OOP) dans lequel
TOUT sauf les valeurs primitives est objet (c’est-à-dire nativement
doté ou pouvant à tout moment être doté de membres [ intrinsèques ] : propriétés représentant des valeurs et méthodes = fonctions). Un membre particulier ou propriété particulière des objets JS
c’est le prototype qui est une propriété au sens OOP figurant une
bibliothèque des propriétés héritables de l’objet en cours. Dans certains langages de programmation les membres des objets complexes
(appelons ces objets « structures ») sont aussi appelés « attributs ».
Techniquement, en JavaScript « attribut » réfère à une caractéristique particulière d’une propriété (attribute : internal value that defines some characteristic of a property - https:/www.ecmainternational.org/ecma-262/8.0).
Mais qui a dit que syntactiquement en JS les classes au look C++,
Smalltalk, ou Java (ou class-iques dit-on) n’existent pas, seuls les
objets et leurs prototypes ? Depuis le standard ECMAScript 2015
Language Specification – ECMA-262 6th Edition, JS dispose d’une
syntaxe spéciale « class » permettant de plus facilement créer des
objets et manipuler leurs prototypes et donc l’héritage.
En fait, class en JS est simplement une syntaxe spéciale pour définir
d’un coup un constructeur et les méthodes (pas les propriétés) de son
prototype. En réalité une class JS n’est ni plus ni moins une fonction : il n’existe pas d’entité spécifique class en JavaScript.
<script type="text/javascript"> "use strict";
let notreClass = class nomClasse {}
console.log(notreClass)
// function nomClasse()
[FIREFOX]
J.D.B. DIASOLUKA Nz. Luyalu
3 / 25
JavaScript Tome-III
Les CLASSES en JavaScript
// class nomClasse {}
[YANDEX]
console.log(typeof notreClass)
// function
</script>
On introduit une définition de classe avec le mot clé « class », et le
constructeur d’une classe ne peut jamais être appelé sans « new ».
Par défaut, le constructeur d’une classe est une fonction vide.
Version class, sans prototype explicitement défini :
<script type="text/javascript"> "use strict";
class Person {
constructor(id) { this.id = id; }
congrat() {
console.log("Hello,",this.id);
// Hello, Brejnev.
}
}
let president = new Person("Brejnev.");
president.congrat();
</script>
Version objet : il faut définir explicitement le prototype.
<script type="text/javascript"> "use strict";
function Person(id) { this.id = id; }
Person.prototype.congrat = function() {
console.log("Hello,",this.id);
}
let president = new Person("Brejnev.");
// president hérite de la méthode congrat
// via le prototype.
president.congrat(); // Hello, Brejnev.
</script>
En fait, l’identifiant de la classe est aussi la fonction constructeur.
J.D.B. DIASOLUKA Nz. Luyalu
4 / 25
JavaScript Tome-III
Les CLASSES en JavaScript
<script type="text/javascript"> "use strict";
var vClass = class ClassName {
constructor(p) {
this.id=p;
};
fct(){console.log("Hello")}
}
console.log(vClass === vClass.prototype.constructor);
// true
console.log(
Object.getOwnPropertyNames(vClass.prototype));
// Array [ "constructor" , "fct" ]
</script>
Une classe JS possède, en plus des propriétés et méthodes comme
dans les objets, un constructeur.
Quelques différences entre « classe » et « objet » :
Programme avec « objet » :
<script type="text/javascript"> "use strict";
function Candidat (p1 = "Kombo", p2 = "00000"){
this.name = p1;
this.matr = p2;
this.msg = function () {
console.log(`Objet: Nom= ${this.name}`,
`Matr=${this.matr}`);
}
}
let n = new Candidat(undefined,2018);
console.log(n);
n.msg();
</script>
J.D.B. DIASOLUKA Nz. Luyalu
5 / 25
JavaScript Tome-III
Les CLASSES en JavaScript
Le même petit programme avec cette fois-ci une « classe » :
<script type="text/javascript"> "use strict";
class Candidat {
constructor(p1 = "Kombo", p2 = "00000") {
this.name = p1;
this.matr = p2;
}
msg() {
console.log(`class: Nom= ${this.name}`,
`Matr=${this.matr}`);
}
}
let n = new Candidat(undefined,2018);
console.log(n);
n.msg();
</script>
Une des différences frappantes c’est que « Objet » reprend la fonction « msg » parmi ses propriétés (plutôt méthodes) propres listées,
alors que « class » le reprend dans son prototype, mais évidemment
les deux l’exécutent.
J.D.B. DIASOLUKA Nz. Luyalu
6 / 25
JavaScript Tome-III
Les CLASSES en JavaScript
Comme on le voit ci-haut, une classe JS possède un constructeur, en
plus des propriétés et méthodes comme tous les autres objets.
Un exemple de l’utilisation de « class » en JavaScript :
<script type="text/javascript"> "use strict";
class Polygon {
constructor(height, ...widths) {
this.name = 'Polygon';
this.height = height;
this.width = widths[1];
}
surf(){return this.height*this.width};
}
J.D.B. DIASOLUKA Nz. Luyalu
7 / 25
JavaScript Tome-III
Les CLASSES en JavaScript
class Rect extends Polygon {
constructor(length,width) {
super(length, null, width||length);
//
this.length = length;
// Définition explicite de « this.length »
// Sans cette définition, « this.length »
// restera « undefined » comme ici.
if(!width) this.name = 'Square';
else this.name = 'Rectan';
}
}
console.log(
new Rect(3,4).name,
new Rect(3,4).length,
new Rect(3,4).width,
new Rect(3,4).height,
new Rect(3,4).surf(),
);
console.log(
new Rect(5).name,
new Rect(5).length,
new Rect(5).width,
new Rect(5).height,
new Rect(5).surf(),
);
</script>
//
//
//
//
//
//
//
//
Rect
undefined
4
3
// 12
Rect
undefined
5
5
// 25
Les corps des classes utilisent automatiquement le mode strict, le
corps des classes (pour les expressions et les déclarations de classes)
est exécuté en mode strict (càd que la méthode constructeur, les méthodes statiques, le prototype, les accesseurs [getters] et les mutateurs [setters] sont exécutés en mode strict).
Un peu plus de détails sur les « class » en JavaScript.
J.D.B. DIASOLUKA Nz. Luyalu
8 / 25
JavaScript Tome-III
Les CLASSES en JavaScript
Les fonctions liées aux classes sont exécutées en mode strict quel
que soit le mode de JS.
Un « constructor » permet de créer et d'initialiser les objets. Lors de
la création d’un objet, l’objet lui-même est son propre constructeur.
Le constructeur d’une classe est explicite et doit être unique.
<script type="text/javascript"> "use strict";
class imc {
constructor(pds,tHt) {
this.icorp = pds / Math.pow(tHt,2);
}
}
let dias=new imc(60,1.65)
console.log(dias.icorp.toFixed(2),"kg/m2");
// 22.04 kg/m2
</script>
Exemple 2 : On peut utiliser une expression de classe, ce qui permet
de re-déclarer une classe déjà définie.
<script type = "text/javascript"> "use strict";
class myClass {};
class myClass {};
</script>
Firefox 64 :
Yandex :
<script type = "text/javascript"> "use strict";
var Foo = myClass {};
J.D.B. DIASOLUKA Nz. Luyalu
9 / 25
JavaScript Tome-III
Les CLASSES en JavaScript
class myClass {};
</script>
Firefox 64 :
Yandex :
Redéclaration d’une même « expression de class » :
<script type = "text/javascript"> "use strict";
var myClass = class {};
var myClass = class {};
</script>
OK, aucune reaction !
Expression simple :
<script type="text/javascript"> "use strict";
var Polygone = class {
constructor(longueur, largeur) {
this.nom = 'Polygone';
this.longueur = longueur/2;
this.largeur = largeur/2;
this.surf=(this.longueur*2)*(this.largeur*2);
this.qsurf=this.longueur*this.largeur;
}
}
let rect = new Polygone(10,15);
console.log("1/4 Surf=",rect.longueur*rect.largeur);
// 1/4 Surf= 37.5
console.log("1/4 Surf=",rect.qsurf);
J.D.B. DIASOLUKA Nz. Luyalu
10 / 25
III
JavaScript Tome-
Les CLASSES en JavaScript
// 1/4 Surf= 37.5
console.log("Surf=",rect.surf);
// Surf= 150
console.log("=========");
console.log(Polygone);
</script>
Firefox Quantum 62.0.2 :
Yandex Version 18.11.1.385 beta :
J.D.B. DIASOLUKA Nz. Luyalu
11 / 25
III
JavaScript Tome-
Les CLASSES en JavaScript
Expression de classe, nommée : permet de faire référence à la classe,
au sein du corps de la classe. Ce nom de classe ne sera visible que du
sein de la portée de l'expression de classe.
<script type="text/javascript"> "use strict";
var vClass = class ClassName {
constructor() {}
leNom() {
return ClassName.name;
}
}
var i = new vClass;
console.log(i.leNom());
// ClassName
///////// console.log(ClassName.name);
// ReferenceError: ClassName is not defined
console.log(vClass.name);
</script>
// ClassName
Syntaxe générale d’une « class » :
var MaClasse = class [nomClasse] [extends] {
// corps de la classe
};
Le mot-clé « extends » (dans les déclarations ou les expressions de
classes) permet de créer une classe héritière (« sous-classe » ou
« classe-fille ») d'une autre.
<script type="text/javascript"> "use strict";
class Creancier {
constructor(id="Russe",q="1000") {
this.nom = id;
this.montant = q;
this.devise = " Roubles"
J.D.B. DIASOLUKA Nz. Luyalu
12 / 25
III
JavaScript Tome-
Les CLASSES en JavaScript
}
clause() {
return(this.nom + ' sollicite ' +
this.montant + this.devise);
}
}
class Debiteur extends Creancier {
clause() {
return(this.nom + ' rembourse ' +
this.montant + this.devise);
// Debiteur hérite de « nom » et « devise » de Creancier.
}
}
let kingandi = new Creancier("Elombe");
console.log(kingandi.clause());
// Elombe sollicite 1000 Roubles
let mosusu = new Debiteur("Boboto",20500);
console.log(mosusu.clause());
// Boboto rembourse 1000 Roubles
let lokuta = new Creancier(undefined,55000);
console.log(lokuta.clause());
// Boboto rembourse 1000 Roubles
</script>
<script type="text/javascript"> "use strict";
class Creancier {
constructor(id="Russe",q="1000") {
this.nom = id;
this.montant = q;
this.devise = " Roubles";
J.D.B. DIASOLUKA Nz. Luyalu
13 / 25
III
JavaScript Tome-
Les CLASSES en JavaScript
this.aspect = " Sérieux";
}
clause() {
return(
`${this.nom} ( ${this.aspect} )`+
` rembourse ${this.montant} ${this.devise}`
);
}
}
class Debiteur extends Creancier {
constructor (
id="Mowuta", q, motif="Projet",
credible=false) {
super(id, q);
this.raison = motif;
this.credi = credible;
this.aspect = "";
}
clause() {
let retval= `${this.nom} ( ${this.aspect} ) `+
`sollicite ${this.montant} ${this.devise}`+
`( ${this.raison} )`;
if(!this.credi) retval+=", refusé";
else retval+=", accordé ";
return retval;
// Debiteur hérite de « nom » et « montant » de Creancier.
}
}
let mosusu = new Creancier();
console.log(mosusu.clause());
// Boboto rembourse 1000 Roubles
let kingandi = new Debiteur(
"Elombe",15500,undefined,1);
console.log(kingandi.clause());
// Elombe sollicite 15500 Roubles (Projet), accordé
J.D.B. DIASOLUKA Nz. Luyalu
14 / 25
III
JavaScript Tome-
Les CLASSES en JavaScript
let lokuta = new Debiteur(
undefined,22500,"Construction");
console.log(lokuta.clause());
// Mowuta sollicite 22500 Roubles (Construction), refusé
let lolendo = new Creancier(
"Yewana",17500,"Lotissement",1);
console.log(lolendo.clause());
// Yewana rembourse 17500 Roubles
</script>
Les mots-clé « extends » et « super » :
« extends » indique que la « class » en cours est descendante (ou est
« extension ») de la classe parente qu’il désigne (qui le suit dans la
syntaxe).
Les arguments de « super » sont passés à la classe parente qui les
reçoit et les utilise en guise de paramètres quand cette classe parent
est appelée à partir de la classe en cours. « super » doit être utilisé
dans un constructeur et avant tout « this » éventuel.
<script type="text/javascript"> "use strict";
class Polygone {
constructor(hauteur, largeur) {
this.nom = 'Polygone';
this.hauteur = hauteur;
this.largeur = largeur;
this.tSurf="Haut="+this.hauteur+
", Larg="+this.largeur
J.D.B. DIASOLUKA Nz. Luyalu
15 / 25
III
JavaScript Tome-
Les CLASSES en JavaScript
this.Surf=this.tSurf+" => "+
this.hauteur*this.largeur
}
calc(){ return "Surf "+
this.nom+": "+this.Surf }
}
class Carré extends Polygone {
constructor(longueur) {
super(longueur);
this.nom = 'Carré';
this.tSurf="Longueur="+longueur
this.Surf=this.tSurf+" => "+
Math.pow(longueur,2);
}
}
class Volume extends Carré {
constructor(longueur,largeur,hauteur) {
super(longueur,largeur,hauteur);
this.nom = 'Volume';
this.tVol="Haut="+hauteur+", Larg="+
largeur+", Long="+longueur
this.Vol=this.tVol+" => "+
longueur*largeur*hauteur;
}
calc(){return this.nom+": "+this.Vol}
}
let iPolyg = new Polygone(10,20);
console.log(iPolyg.calc());
// Surf Polygone: Haut=10, Larg=20 => 200
let iSurf = new Carré(17);
console.log(iSurf.calc());
// Surf Carré: Longueur=17 => 289
let iVol = new Volume(3,5,7);
console.log(iVol.calc());
// Volume: Haut=7, Larg=5, Long=3 => 105
</script>
J.D.B. DIASOLUKA Nz. Luyalu
16 / 25
III
JavaScript Tome-
Les CLASSES en JavaScript
Appel d’une méthode du parent (super) à partir d’une classe fille :
<script type="text/javascript"> "use strict";
function Voiture (nom) {
this.nom = nom;
}
Voiture.prototype.roule = function () {
console.log(this.nom + ' file très vite.');
// Ferari file très vite.
}
class deRally extends Voiture {
roule() {
super.roule();
// Ferari file très vite (ligne 6).
console.log(this.nom + ' chancelle.');
// Ferari chancelle.
}
}
let v = new deRally('Ferari');
v.roule();
</script>
J.D.B. DIASOLUKA Nz. Luyalu
17 / 25
III
JavaScript Tome-
Les CLASSES en JavaScript
Prototype et « super » !
<script type="text/javascript"> "use strict";
var Voiture = {
roule() {
console.log(this.nom + ' file très vite.');
}
};
class deRally {
constructor(nom) {
this.nom = nom;
}
roule() {
super.roule();
console.log(this.nom + ' traîne.');
}
}
Object.setPrototypeOf(deRally.prototype, Voiture);
// Donne accès aux méthodes de Voiture.
var d = new deRally('Ferari');
d.roule();
</script>
Les classes peuvent inclure des getters et des setters :
<script type="text/javascript"> "use strict";
class User {
constructor(idName) {
console.log("Ds constructor.");
this.idName = idName; // invoque le setter
}
J.D.B. DIASOLUKA Nz. Luyalu
18 / 25
III
JavaScript Tome-
Les CLASSES en JavaScript
get idName() {
console.log(this._idName,"- de get");
return this._idName;
}
set idName(value) {
console.log("Ds setter.");
if (value.length < 4) {
console.log("idName trop court.");
return;
}
this._idName = value;
}
}
console.log('Avant let user=new User("John")');
let user = new User("Jerry");
console.log('Avant [console.log(user.idName)]');
console.log(user.idName,"- direct"); // Jerry
console.log('Avant user=new User("")');
user = new User("Jerry"); // idName trop court.
console.log('The END!');
</script>
Exécution-tracée:
J.D.B. DIASOLUKA Nz. Luyalu
19 / 25
III
JavaScript Tome-
Les CLASSES en JavaScript
« symbole . species » permet de surcharger le constructeur par défaut d’une méthode qui renvoie un objet Array avec une sous-classe
par exemple MonArray e.g. la méthode map() , par exemple pour
modifier le format <du résultat.
<script type="text/javascript"> "use strict";
class MonArray extends Array {
static get [Symbol.species]() { return Object; }
// On surcharge species avec le constructeur Object
}
var a = new MonArray("2","4","6");
console.log(a instanceof MonArray); // true
var mapped = a.map(x => x * x);
console.log(mapped); // Number {3, 0: 4, 1: 16, 2: 36}
console.log(MonArray); //class MonArray extends Array {}
console.log(mapped
console.log(mapped
console.log(mapped
console.log(mapped
instanceof
instanceof
instanceof
instanceof
MonArray);
Array);
Object);
Number);
//
//
//
//
false
false
true
true
console.log("==========");
class MonArray2 extends Array {
static get [Symbol.species]() { return Array; }
// On surcharge species avec le constructeur Array
}
var a = new MonArray2("2","4","6");
var mapped = a.map(x => x * x);
console.log(mapped);// Array [ 4, 16, 36 ]
console.log(MonArray); //class MonArray extends Array {}
console.log(mapped instanceof MonArray2); // false
console.log(mapped instanceof Array);
// true
console.log(mapped instanceof Object);
// true
console.log(mapped instanceof Number);
// false
</script>
J.D.B. DIASOLUKA Nz. Luyalu
20 / 25
III
JavaScript Tome-
Les CLASSES en JavaScript
J.D.B. DIASOLUKA Nz. Luyalu
21 / 25
III
JavaScript Tome-
Les CLASSES en JavaScript
Kinshasa, le jeudi 4 avril 2019 - 10:47:46 PM
Mots-clés :
JAVASCRIPT, Programmation Internet, fonction fléchée, sloppy
mode, mode strict, prototype, objet ordinaire, objet exotique, objet
standard, built-in object, Scope, contexte d’exécution, Domaine, Portée, Étendue, Visibilité, Accessibilité, durée de vie, Es8,
ECMASCRIPT, LiveScript, extra-dimensionnels, entités éthériques
non-biologiques, TC39, ECMA, Kaprekar
J.D.B. DIASOLUKA Nz. Luyalu
22 / 25
III
JavaScript Tome-
Les CLASSES en JavaScript
DIASOLUKA Nz. Luyalu
Docteur en Médecine, Chirurgie & Accouchements (1977),
CNOM : 0866 - Spécialiste en ophtalmologie (1980)
Études humanités : Scientifique - Mathématiques & Physique.
Informaticien-amateur, Programmeur et WebMaster.
Chercheur indépendant, autonome et autofinancé, bénévole, sans
aucun conflit d’intérêt ou liens d'intérêts ou contrainte
promotionnelle avec qui qu’il soit ou quelqu’organisme ou
institution / organisation que ce soit, étatique, paraétatique ou
privé, industriel ou commercial en relation avec le sujet présenté.
+243 - 851278216 - 899508675 - 991239212 - 902263541 - 813572818
[email protected]
Autre Lecture :
https://www.scribd.com/document/374738470/Le-Plus-Grand-Secret-de-LaCreation
D’autres publications pouvant aussi intéresser :
• https://www.scribd.com/document/377036251/LeDosage-Des-Medicaments-en-Cac-Cas
• https://www.scribd.com/document/377035454/LeHasard-Des-Thermometres-Non-contact-a-Infrarouge
J.D.B. DIASOLUKA Nz. Luyalu
23 / 25
III
JavaScript Tome-
Les CLASSES en JavaScript
• https://www.scribd.com/document/376222482/PetiteIntroduction-Aux-Fonctions-JavaScript
• https://www.scribd.com/document/376221919/La-Foien-Jesus-Christ-Pour-Quoi-Faire
• https://www.scribd.com/document/375689778/Lacuitevisuelle-angulaire
• https://www.scribd.com/document/375349851/Lavariable-This
•
https://www.scribd.com/document/375024162/FonctionsImbriquees-en-JS
• https://www.scribd.com/document/374789297/FormatInterne-Des-Objets-JavaScript
•
https://www.scribd.com/document/374788758/Iterationsen-JavaScript
• https://www.scribd.com/document/374738470/Le-PlusGrand-Secret-de-La-Creation
• https://www.scribd.com/document/374597969/NouvelleFormule-d-IMC-indice-de-doduite-Selon-Dr-Diasoluka
• https://www.scribd.com/document/373847209/PropertyDescriptors
• https://www.scribd.com/document/373833282/l-ObjetGlobal-Window
•
https://www.scribd.com/document/372665249/JavascriptTome-II
J.D.B. DIASOLUKA Nz. Luyalu
24 / 25
III
JavaScript Tome-
Les CLASSES en JavaScript
• https://www.scribd.com/document/355291488/motiliteoculaire-2
• https://www.scribd.com/document/355291239/motiliteoculaire-I
• https://www.scribd.com/document/355290248/Script-dAnalyses-Des-Reflexes-Pupillomoteurs
•
https://www.scribd.com/document/321168468/Renseigne
ments-Id-et-Anthropometriques
•
https://www.scribd.com/document/320856721/Emission31-Jul-2016
•
https://www.scribd.com/document/318182982/Complicati
on-Visuelle-du-Traitement-de-La-Malaria
• https://www.scribd.com/document/318180637/RapportEntre-Oxymetrie-Et-Type-Respiration
•
https://www.scribd.com/document/315746265/Classificati
on-Des-Medicaments
•
https://www.scribd.com/document/315745909/Incongruen
ces-Heresies-et-Heterodoxies-de-la-Notion-deLaboratoire
• https://www.scribd.com/document/315745725/RapportEntre-Oxymetrie-Et-Type-Respiration
J.D.B. DIASOLUKA Nz. Luyalu
25 / 25
III
JavaScript Tome-