devstory

Techniques de simulation classe et héritage en JavaScript

  1. Classe en Javascript
  2. Classe et héritage en ES3
  3. Classe et Héritage en ES5

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 :
  • L'objet 'rect' est créé (il est juste un objet normal, rien est particulier)
  • Ajoutez la propriété (property) __proto__ à l'objet 'rect', ceci est une propriété cachée.
  • La variable this sera pointé à l'adresse de l'objet 'rect'.
  • Ajoutez la propriété (property) width à l'objet 'rect'.
  • 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.
  • La classe Animal comprend deux propriétés (property) name & gender.
  • 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 (ES5 + 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

Tutoriels de programmation ECMAScript, Javascript

Show More