Aperçu

En ES6, la classe (class) est introduite comme modèle pour les objets, et les classes peuvent être définies à l'aide du mot-clé class.

L'essence d'une classe est une fonction.

Elle peut être considérée comme du sucre syntaxique, rendant la syntaxe du prototype d'objet plus claire et plus proche de la syntaxe de la programmation orientée objet.

Utilisation de base

Définition de classe

Les expressions de classe peuvent être anonymes ou nommées.

//Classe anonyme let Exemple = class { constructor(a) { this.a = a; } } //Classe nommée let Example = class Exemple { constructor(a) { this.a = a; } }

Déclaration de classe

class Exemple { constructor(a) { this.a = a; } }

Remarque importante : ne peut pas être redéclaré.

class Example{} class Example{} // Uncaught SyntaxError: L'identifiant 'Example' a déjà été // déclaré let Example1 = class{} class Example{} // Uncaught SyntaxError: L'identifiant 'Example' a déjà été // déclaré

Remarques importantes

Les définitions de classe ne sont pas hissées, ce qui signifie que vous devez définir une classe avant d'y accéder, sinon une erreur sera levée.

Les méthodes dans une classe ne nécessitent pas le mot-clé function.

Les points-virgules ne peuvent pas être ajoutés entre les méthodes.

new Example(); class Example {}

Corps de classe

Propriétés

prototype

En ES6, le prototype existe toujours. Bien que les méthodes puissent être définies directement dans la classe, elles sont en fait toujours définies sur le prototype. Redéfinir les méthodes / Ajouter des méthodes lors de l'initialisation

Example.prototype={ //methods }

Ajouter des méthodes

Object.assign(Example.prototype,{ //méthodes })

Propriétés statiques

Propriétés statiques : propriétés de la classe elle-même, c'est-à-dire propriétés définies directement à l'intérieur de la classe (Class.propname), qui ne nécessitent pas d'instanciation. En ES6, il est précisé que la classe ne possède que des méthodes statiques, pas de propriétés statiques.

class Example { //Nouvelle proposition static a = 2; } //Approche actuellement réalisable Exemple.b = 2;

Propriétés publiques

class Example{} Example.prototype.a = 2;

Propriétés d'instance

Propriétés d'instance : propriétés définies sur l'objet d'instance (this).

class Example { a = 2; constructor () { console.log(this.a); } }

propriété name

Renvoie le nom de la classe suivant class (si présent).

let Example=class Exam { constructor(a) { this.a = a; } } console.log(Example.name); // Exam let Example=class { constructor(a) { this.a = a; } } console.log(Example.name); // Example

Méthodes

méthode constructor

La méthode constructor est la méthode par défaut d'une classe et est appelée lors de la création d'un objet instance de la classe.

class Example{ constructor(){ console.log('Je suis constructor'); } } new Example(); //Je suis constructor

Retourner un objet

class Test { constructor(){ //Renvoie l’objet instance this par défaut } } console.log(new Test() instanceof Test); // true class Example { constructor(){ //Spécifier l’objet retourné return new Test(); } } console.log(new Example() instanceof Example); // false

Méthodes statiques

class Example{ static sum(a, b) { console.log(a+b); } } Example.sum(1, 2); // 3

Méthodes de prototype

class Example { sum(a, b) { console.log(a + b); } } let exam = new Example(); exam.sum(1, 2); // 3

Méthodes d'instance

class Exemple { constructor() { this.sum = (a, b) => { console.log(a + b); } } }

Instanciation de classe

nouveau

L'instanciation d'une classe doit utiliser le mot-clé new.

class Example {} let exam1 = Example(); // Le constructeur de classe Example ne peut pas être invoqué sans 'new'

Objet instancié

Objet prototype partagé

class Exemple { constructor(a, b) { this.a = a; this.b = b; console.log('Example'); } sum() { return this.a + this.b; } } let exam1 = new Example(2, 1); let exam2 = new Example(3, 1); //__proto__ est obsolète et non recommandé. // console.log(exam1.__proto__ == exam2.__proto__); console.log(Object.getPrototypeOf(exam1) === Object.getPrototypeOf(exam2));// true Object.getPrototypeOf(exam1).sub = function() { return this.a - this.b; } console.log(exam1.sub()); // 1 console.log(exam2.sub()); // 2

décorateur

Un décorateur est une fonction utilisée pour modifier le comportement d'une classe, prenant effet au moment de la compilation du code.

Décorateur de classe

Un paramètre

Le premier paramètre, target, pointe vers la classe elle-même.

function testable(target) { target.isTestable = true; } @testable class Example {} Example.isTestable; // vrai

Plusieurs paramètres — implémentation imbriquée

function testable(isTestable) { return function(target) { target.isTestable=isTestable; } } @testable(true) class Example {} Example.isTestable; // true

Propriétés d'instance

Les deux exemples ci-dessus ajoutent des propriétés statiques. Pour ajouter des propriétés d'instance, il suffit d'opérer sur le prototype de la classe.

Décorateur de méthode

Trois paramètres : target (l'objet prototype de la classe), name (le nom de la propriété modifiée), descriptor (l'objet descripteur de la propriété).

class Example { @writable sum(a, b) { return a + b; } } function writable(target, name, descriptor) { descriptor.writable = false; return descriptor; //Doit retourner }

Ordre d'exécution des décorateurs

Entre de l'extérieur vers l'intérieur, s'exécute de l'intérieur vers l'extérieur.

class Example { @logMethod(1) @logMethod(2) sum(a, b){ return a + b; } } function logMethod(id) { console.log('logMethod évalué'+id); return (target, name, desctiptor) => console.log('logMethod exécuté '+id); } // logMethod 1 évalué // logMethod 2 évalué // logMethod 2 exécuté // logMethod 1 exécuté

Encapsulation et héritage

getter / setter

Définition

class Exemple{ constructor(a, b) { this.a = a; //La méthode set est appelée lors de l'instanciation this.b = b; } get a(){ console.log('getter'); return this.a; } set a(a){ console.log('setter'); this.a = a; //Appel auto-récursif } } let exam = new Example(1,2); //Affiche continuellement setter, ce qui finit par provoquer une RangeError class Example1{ constructor(a, b) { this.a = a; this.b = b; } get a(){ console.log('getter'); return this._a; } set a(a){ console.log('setter'); this._a = a; } } let exam1 = new Example1(1,2); //N'affiche que setter, n'appelle pas la méthode getter console.log(exam1._a); //1, est accessible directement

getter ne peut pas apparaître seul

class Exemple { constructor(a) { this.a = a; } get a() { return this.a; } } let exam = new Example(1); // TypeError non interceptée : Impossible de définir la propriété // a de #<Example> qui n'a qu'un getter

getter et setter doivent apparaître au même niveau

class Father { constructor(){} get a() { return this._a; } } class Child extends Father { constructor(){ super(); } set a(a) { this._a = a; } } let test = new Child(); test.a = 2; console.log(test.a); // undefined class Father1 { constructor(){} //Ou mettez les deux dans la sous-classe get a() { return this._a; } set a(a) { this._a = a; } } class Child1 extends Father1 { constructor(){ super(); } } let test1 = new Child1(); test1.a = 2; console.log(test1.a); // 2

extends

L'héritage des classes est implémenté via extends.

class Child extends Father { ... }

super

La méthode constructeur de la sous-classe doit contenir super, et elle doit apparaître avant this.

class Father { constructor() {} } class Child extends Father { constructor() {} // ou // constructor(a) { // this.a = a; // super(); // } } let test = new Child(); // ReferenceError non interceptée: il faut appeler super // constructeur dans la classe dérivée avant d'accéder à 'this' ou de retourner // depuis le constructeur dérivé

L'appel du constructeur de la classe parente ne peut apparaître que dans le constructeur de la sous-classe.

class Father { test(){ return 0; } static test1(){ return 1; } } class Child extends Father { constructor(){ super(); } } class Child1 extends Father { test2() { super(); // SyntaxError non interceptée : mot-clé 'super' inattendu // ici } }

Appel des méthodes de la classe parente : super, en tant qu'objet, pointe vers l'objet prototype de la classe parente dans les méthodes normales, et vers la classe parente dans les méthodes statiques.

class Child2 extends Father { constructor(){ super(); //Appel des méthodes normales de la classe parente console.log(super.test()); // 0 } static test3(){ //Appel des méthodes statiques de la classe parente return super.test1+2; } } Child2.test3(); // 3

Remarques importantes

Impossible d'hériter d'objets réguliers.

var Father = { // ... } class Child extends Father { // ... } // TypeError non interceptée : la valeur étendue par la classe #<Object> n'est pas un constructeur ou null //Solution Object.setPrototypeOf(Child.prototype, Father);