JavaScript n'est pas un langage orienté objet basé sur des classes. Mais il a toujours des moyens d'utiliser la programmation orientée objet (POO).
Dans ce tutoriel, je vais vous expliquer la POO et vous montrer comment l'utiliser.
Selon Wikipédia, la programmation basée sur les classes est
un style de programmation orientée objet (POO) dans lequel l'héritage se produit via la définition de classes d'objets, au lieu de l'héritage se produisant via les objets seuls
Le modèle de POO le plus populaire est basé sur les classes.
Mais comme je l'ai mentionné, JavaScript n'est pas un langage basé sur des classes - c'est un langage basé sur un prototype.
D'après la documentaion de Mozilla:
Un langage basé sur un prototype a la notion d'objet prototypique, un objet utilisé comme modèle à partir duquel obtenir les propriétés initiales d'un nouvel objet.
Jetez un œil à ce code:
let names = { fname: "Dillion", lname: "Megida" } console.log(names.fname); console.log(names.hasOwnProperty("mname")); // Expected Output // Dillion // false
La variable objet names
n'a que deux propriétés - fname
et lname
. Aucune méthode du tout.
Alors d'où hasOwnProperty
vient-il?
Eh bien, cela vient du Object
prototype.
Essayez de consigner le contenu de la variable sur la console:
console.log(names);
Lorsque vous développez les résultats dans la console, vous obtenez ceci:

Remarquez la dernière propriété - __proto__
? Essayez de le développer:

Vous verrez un ensemble de propriétés sous le Object
constructeur. Toutes ces propriétés proviennent du Object
prototype global . Si vous regardez de près, vous remarquerez également notre caché hasOwnProperty
.
En d 'autres termes, tous les objets ont accès au Object
prototype du. Ils ne possèdent pas ces propriétés, mais ont accès aux propriétés du prototype.
La __proto__
propriété
Cela pointe vers l'objet qui est utilisé comme prototype.
Il s'agit de la propriété de chaque objet qui lui donne accès à la Object prototype
propriété.
Chaque objet a cette propriété par défaut, qui fait référence au Object Protoype
sauf lorsqu'il est configuré autrement (c'est-à-dire lorsque l'objet __proto__
est pointé vers un autre prototype).
Modifier la __proto__
propriété
Cette propriété peut être modifiée en indiquant explicitement qu'elle doit faire référence à un autre prototype. Les méthodes suivantes sont utilisées pour y parvenir:
Object.create()
function DogObject(name, age) { let dog = Object.create(constructorObject); dog.name = name; dog.age = age; return dog; } let constructorObject = { speak: function(){ return "I am a dog" } } let bingo = DogObject("Bingo", 54); console.log(bingo);
Dans la console, voici ce que vous auriez:

Remarquez la __proto__
propriété et la speak
méthode?
Object.create
utilise l'argument qui lui est passé pour devenir le prototype.
new
mot-clé
function DogObject(name, age) { this.name = name; this.age = age; } DogObject.prototype.speak = function() { return "I am a dog"; } let john = new DogObject("John", 45);
john
La __proto__
propriété de est dirigée vers DogObject
le prototype de. Mais rappelez-vous, DogObject
le prototype de est un objet ( paire clé et valeur ), donc il a aussi une __proto__
propriété qui fait référence au Object
protoype global .
Cette technique est appelée PROTOTYPE CHAINING .
Notez que: l' new
approche par mot - clé fait la même chose, Object.create()
mais la rend seulement plus facile car elle fait certaines choses automatiquement pour vous.
Et donc...
Chaque objet en Javascript a accès au Object
prototype de par défaut. S'il est configuré pour utiliser un autre prototype, par exemple prototype2
, il prototype2
aurait également accès au prototype de l'objet par défaut, et ainsi de suite.
Combinaison objet + fonction
Vous êtes probablement confus par le fait qu'il DogObject
s'agit d'une fonction ( function DogObject(){}
) et qu'elle possède des propriétés accessibles avec une notation par points . C'est ce qu'on appelle une combinaison d'objets de fonction .
Lorsque les fonctions sont déclarées, par défaut, de nombreuses propriétés leur sont associées. N'oubliez pas que les fonctions sont également des objets dans les types de données JavaScript.
Maintenant, classe
JavaScript a introduit le class
mot - clé dans ECMAScript 2015. Il donne l'impression que JavaScript est un langage POO. Mais ce n'est que du sucre syntatique par rapport à la technique de prototypage existante. Il continue son prototypage en arrière-plan mais fait ressembler le corps extérieur à la POO. Nous allons maintenant voir comment cela est possible.
L'exemple suivant est une utilisation générale de a class
en JavaScript:
class Animals { constructor(name, specie) { this.name = name; this.specie = specie; } sing() { return `${this.name} can sing`; } dance() { return `${this.name} can dance`; } } let bingo = new Animals("Bingo", "Hairy"); console.log(bingo);
Voici le résultat dans la console:

Les __proto__
références au Animals
prototype (qui à son tour fait référence au Object
prototype).
À partir de là, nous pouvons voir que le constructeur définit les fonctionnalités majeures tandis que tout ce qui est en dehors du constructeur ( sing()
et dance()
) sont les fonctionnalités bonus ( prototypes ).
En arrière-plan, en utilisant l' new
approche par mot - clé, ce qui précède se traduit par:
function Animals(name, specie) { this.name = name; this.specie = specie; } Animals.prototype.sing = function(){ return `${this.name} can sing`; } Animals.prototype.dance = function() { return `${this.name} can dance`; } let Bingo = new Animals("Bingo", "Hairy");
Sous-classement
Il s'agit d'une fonctionnalité de la POO où une classe hérite des fonctionnalités d'une classe parent mais possède des fonctionnalités supplémentaires que le parent n'a pas.
The idea here is, for example, say you want to create a cats class. Instead of creating the class from scratch - stating the name, age and species property afresh, you'd inherit those properties from the parent animals class.
This cats class can then have extra properties like color of whiskers.
Let's see how subclasses are done with class
.
Here, we need a parent which the subclass inherits from. Examine the following code:
class Animals { constructor(name, age) { this.name = name; this.age = age; } sing() { return `${this.name} can sing`; } dance() { return `${this.name} can dance`; } } class Cats extends Animals { constructor(name, age, whiskerColor) { super(name, age); this.whiskerColor = whiskerColor; } whiskers() { return `I have ${this.whiskerColor} whiskers`; } } let clara = new Cats("Clara", 33, "indigo");
With the above, we get the following outputs:
console.log(clara.sing()); console.log(clara.whiskers()); // Expected Output // "Clara can sing" // "I have indigo whiskers"
When you log the contents of clara out in the console, we have:

You'll notice that clara
has a __proto__
property which references the constructor Cats
and gets access to the whiskers()
method. This __proto__
property also has a __proto__
property which references the constructor Animals
thereby getting access to sing()
and dance()
. name
and age
are properties that exist on every object created from this.
Using the Object.create
method approach, the above translates to:
function Animals(name, age) { let newAnimal = Object.create(animalConstructor); newAnimal.name = name; newAnimal.age = age; return newAnimal; } let animalConstructor = { sing: function() { return `${this.name} can sing`; }, dance: function() { return `${this.name} can dance`; } } function Cats(name, age, whiskerColor) { let newCat = Animals(name, age); Object.setPrototypeOf(newCat, catConstructor); newCat.whiskerColor = whiskerColor; return newCat; } let catConstructor = { whiskers() { return `I have ${this.whiskerColor} whiskers`; } } Object.setPrototypeOf(catConstructor, animalConstructor); const clara = Cats("Clara", 33, "purple"); clara.sing(); clara.whiskers(); // Expected Output // "Clara can sing" // "I have purple whiskers"
Object.setPrototypeOf
is a method which takes in two arguments - the object (first argument) and the desired prototype (second argument).
From the above, the Animals
function returns an object with the animalConstructor
as prototype. The Cats
function returns an object with catConstructor
as it's prototype. catConstructor
on the other hand, is given a prototype of animalConstructor
.
Therefore, ordinary animals only have access to the animalConstructor
but cats have access to the catConstructor
and the animalConstructor
.
Wrapping Up
JavaScript leverages its prototype nature to welcome OOP developers to its ecosystem. It also provides easy ways to creating prototypes and organize related data.
True OOP languages do not perform prototyping in the background - just take note of that.
A big thanks to Will Sentance's course on Frontend Masters - JavaScript: The Hard Parts of Object Oriented JavaScript. I learned everything you see in this article (plus a little extra research) from his course. You should check it out.
You can hit me up on Twitter at iamdillion for any questions or contributions.
Thanks for reading : )
Useful Resources
- Object-oriented JavaScript for beginners
- Introduction to Object Oriented Programming in JavaScript