Techniques de simulation classe et héritage en ECMAScript

View more Tutorials:

1- Classe en Javascript

Javascript signifie en fait un univer de fonctions et d'objets. A l'origine, il est conçu simple, n'a pas de concept clair de classes. Peut-être que les créateurs de Javascript ne peuvent pas penser qu'un jour ce langage est utilisée si largement.
L'objet en  Javascript est en fait une entité de multiples paires  "Clé/ Valeur" et vous pouvez accéder aux valeurs à travers des objets et des clés.
object-example1.js
var tom =  {
  name: "Tom",
  country: "USA"
};

// Access:
console.log( tom.name ); // Tom
console.log( tom.country ); // USA
console.log( tom["name"] ); // Tom
console.log( tom["country"] ); // USA
 
Vous pouvez ajouter des nouvelles paires "Clé/ Valeur" à un objet disponible ou enlever ses paires  "Clé/ Valeur".
object-example2.js
var tom =  {
  name: "Tom",
  country: "USA"
};

// Delete property - country
delete tom["country"]; // Same as: delete tom.country;

// Add property - gender
tom["gender"] = "Male"; // Same as: tom.gender = "Male";


// Access:
console.log( tom.name ); // Tom
console.log( tom["name"] ); // Tom

console.log( tom["country"] ); // undefined
console.log( tom.country ); // undefined

console.log( tom["gender"] ); // Male
console.log( tom.gender ); // Male
Classe est un concept moderne dans les langages tels que  Java, C#,... Classe est une conception. L'utilisation cette conception vous permet de créer rapidement des objets avec la même structure. La première version de  Javascript ne contient pas ce concept.
Javascript devient de plus en plus important donc il doit être mis au niveau. Des concepteurs de Javascript essayent de simuler le concept de classe basé sur les concepts disponibles dans Javascript. La syntaxe de simulation d'une classe est introduite dans ES3, ES5, mais pas avant ES6, nous avons une syntaxe moderne qui satisfait tout le monde.
Tout d'abord, pour simplifier, observe une syntaxe moderne introduite en  ECMAScript 6 pour créer la classe  Rectangle, avec des 2 propriétés (property) telles que  width (largeur) et  height (hauteur). Cette classe contient une méthode  getArea() qui donne la supercifie de ce rectangle.
es6-class-example.js
// ECMAScript 6 class:

class Rectangle  {

  constructor (width , height)  {
      this.width = width;
      this.height = height;
  }

  getArea()  {
    return this.width * this.height;
  }

}


// ------------- TEST -------------------

var rect = new Rectangle(10, 5);

var area = rect.getArea();

console.log("Width: " + rect.width);
console.log("Height: " + rect.height);
console.log("Area: " + area);

 
La création d'une sous- classe est tellement simple avec  ES6 :
es6-inheritance-example.js
class Shape  {

    constructor( x, y) {
        this.setLocation(x, y);
    }

    setLocation(x, y) {
        this.x = x;
        this.y = y;
    }
}

// Subclass:
class Circle extends Shape {

    constructor(x, y, radius) {
        // Call Shape's constructor via super
        super(x, y);
        this.radius = radius;
    }

    getArea() {
      return Math.PI * this.radius * this.radius;
    }
}

// ----- TEST ----


var circle = new Circle(0, 2, 5);

console.log( circle.getArea() );

 
ES6 introduit une syntaxe moderne de création d'une classe et des sous-classes mais la technique ne change pas vraiment. La syntaxe de l' ES6 masque les concepts confus de Javascript lorsque celui-ci essaie de simuler une classe. Dans cette leçon, je discute avec vous de la manière dont ES3 & ES5 ont simulé une classe et un héritage.

2- Classe et héritage en ES3

ES3 utilise le mot clé  function afin de définir  "constructeur d'objet". Vous allez créer un nouvel objet lorsque vous appelez cette fonction avec l'opérateur  new :
// ECMAScript 3 class.

function Rectangle(width, height)  {
   this.width = width;
   this.height = height;
}

// Create an Object:
var rect = new Rectangle(10, 5);
 
La figure ci-dessous illustre l'action effectué par la machine d'exécution  Javascript :
  1. L'objet 'rect' est créé (il est juste un objet normal, rien est particulier)
  2. Ajoutez la propriété (property) __proto__ à l'objet 'rect', ceci est une propriété cachée.
  3. La variable this sera pointé à l'adresse de l'objet 'rect'.
  4. Ajoutez la propriété (property) width à l'objet 'rect'.
  5. Ajoutez la propriété (property) height à l'objet​​​​​​​ 'rect'.
Des concepts  prototype sont également introduits en  ES3. Voyons quel est son but ?
// ECMAScript 3 class.

function Rectangle(width, height)  {
   this.width = width;
   this.height = height;
}

Rectangle.prototype.bgColor = "red";
Rectangle.prototype.borderColor = "blue";

// Create an Object:
var rect = new Rectangle(10, 5);



console.log(rect); // Rectangle { width: 10, height: 5 }
console.log(rect.__proto__); // Rectangle { bgColor: 'red',borderColor: 'blue' }

console.log(rect.__proto__.bgColor); // red
console.log(rect.__proto__.borderColor); // blue

// (Read the explanation**)
console.log(rect.bgColor); // red
console.log(rect.borderColor); // blue

 
Que se passe-t-il lorsque le moteur d'exécution JavaScript rencontre l'expression myObject.myProperty ?
  • La réponse est qu'il va vérifier si l'objet myObject contient la propriété (property) myProperty ou non.  Le cas échéant, il accède à cette propriété et inversement il y accède myObject.__proto__.myProperty.
es3-proto-example3.js
var rect =  {
   __proto__ : { bgColor : "red", borderColor : "blue" },
   width: 10,
   height: 5
}


console.log(rect.width); // 10

console.log(rect.__proto__.bgColor); // red


console.log(rect.bgColor); // red

 

new AFunction(args) vs AFunction.call(anObj, args)

Héritage

Avec  ES3 vous pouvez simuler une classe qui hérite d'une autre classe de différentes manières. Bien sûr, ce n'est pas aussi facile que dans ES6 et c'est assez déroutant pour de nombreux programmeurs.
Pour simplifier, je vous donne un exemple de l'héritage et j'analyse la règle de fonctionnement de l'exécution  Javascript dans ce cas.
  1. La classe Animal comprend deux propriétés (property) name & gender.
  2. La classe Cat hérite de la classe Animal, il contient une propriété color.
es3-inheritance-example1.js
function Animal(n, g) {
    this.name = n;
    this.gender = g;
}


function Cat(n, g, c) {
    Animal.call(this, n, g);
    this.color = c;
}


var tom = new Cat("Male", "Tom", "Black");

// Cat { gender: 'Male', name: 'Tom', color: 'Black' }
console.log(tom);

Héritage et rôle de prototype (ES3)

es3-inheritance-example2.js

// Class: Animal
function Animal(n, g) {
    this.name = n;
    this.gender = g;
}

Animal.prototype.sleep = function()  {
    console.log("Animal sleeping..");
}

Animal.prototype.move = function()  {
    console.log("Animal moving..");
}

// Class: Cat
function Cat(n, g, c) {
    Animal.call(this, n, g); // IMPORTANT!!
    this.color = c;
}

// IMPORTANT!!
var TempFunc = function() {}; // Temporary class.
TempFunc.prototype = Animal.prototype;
Cat.prototype = new TempFunc();
// ------------------


Cat.prototype.cry = function()  {
    console.log("Meo meo");
}

// Override 'move' method of Animal.
Cat.prototype.move = function() {
    console.log("Cat moving..");
}

var tom = new Cat("Male", "Tom", "Black");

// Cat { gender: 'Male', name: 'Tom', color: 'Black' }
console.log(tom);

tom.move(); // Cat moving..
tom.sleep(); // Animal sleeping..
tom.cry(); // Meo meo
 

3- Classe et Héritage en ES5

Object.create(srcObject)

La méthode  Object.create(srcObject) crée un nouvel objet  newObject, alors  newObject.__proto__ est la copie de  srcObject.
method-object-create-example.js
var john = {
  name: "John",
  gender: "Male"
};

var other = Object.create(john);


console.log(other.__proto__); // { name: 'John', gender: 'Male' }
 

Héritage (ES3 + Object.create)

L'utilisation de la méthode  Object.create(srcObject) de  ES5 vous permet de simuler la classe et l'héritage plus facilement que  ES3.
es5-inheritance-example1.js
// Class: Animal
function Animal(n, g) {
    this.name = n;
    this.gender = g;
}

Animal.prototype.sleep = function()  {
    console.log("Animal sleeping..");
}

Animal.prototype.move = function()  {
    console.log("Animal moving..");
}

// Class: Cat
function Cat(n, g, c) {
    Animal.call(this, n, g); // IMPORTANT!!
    this.color = c;
}

Cat.prototype = Object.create(Animal.prototype); // IMPORTANT!!

Cat.prototype.cry = function()  {
    console.log("Meo meo");
}

// Override 'move' method of Animal.
Cat.prototype.move = function() {
    console.log("Cat moving..");
}

var tom = new Cat("Male", "Tom", "Black");

// Cat { gender: 'Male', name: 'Tom', color: 'Black' }
console.log(tom);

tom.move(); // Cat moving..
tom.sleep(); // Animal sleeping..
tom.cry(); // Meo meo

View more Tutorials: