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-