JavaScript ist keine klassenbasierte objektorientierte Sprache. Es gibt jedoch immer noch Möglichkeiten zur Verwendung der objektorientierten Programmierung (OOP).
In diesem Tutorial erkläre ich OOP und zeige Ihnen, wie man es benutzt.
Klassenbasierte Programmierung ist laut Wikipedia
Ein Stil der objektorientierten Programmierung (OOP), bei dem die Vererbung über das Definieren von Objektklassen erfolgt, anstatt dass die Vererbung nur über die Objekte erfolgt
Das beliebteste Modell von OOP ist klassenbasiert.
Wie bereits erwähnt, handelt es sich bei JavaScript nicht um eine klassenbasierte Sprache, sondern um eine prototypbasierte Sprache.
Nach Mozillas Dokumentation:
Eine prototypbasierte Sprache hat den Begriff eines prototypischen Objekts, eines Objekts, das als Vorlage verwendet wird, um die anfänglichen Eigenschaften für ein neues Objekt abzurufen.
Schauen Sie sich diesen Code an:
let names = { fname: "Dillion", lname: "Megida" } console.log(names.fname); console.log(names.hasOwnProperty("mname")); // Expected Output // Dillion // false
Die Objektvariable names
hat nur zwei Eigenschaften - fname
und lname
. Überhaupt keine Methoden.
Woher kommt also hasOwnProperty
?
Nun, es kommt vom Object
Prototyp.
Versuchen Sie, den Inhalt der Variablen in der Konsole zu protokollieren:
console.log(names);
Wenn Sie die Ergebnisse in der Konsole erweitern, erhalten Sie Folgendes:

Beachten Sie die letzte Eigenschaft - __proto__
? Versuchen Sie es zu erweitern:

Unter dem Object
Konstruktor wird eine Reihe von Eigenschaften angezeigt. Alle diese Eigenschaften stammen vom globalen Object
Prototyp. Wenn Sie genau hinschauen, werden Sie auch unser verstecktes bemerken hasOwnProperty
.
Mit anderen Worten, alle Objekte haben Zugriff auf den Object
Prototyp des Objekts . Sie besitzen diese Eigenschaften nicht, erhalten jedoch Zugriff auf die Eigenschaften des Prototyps.
Das __proto__
Eigentum
Dies zeigt auf das Objekt, das als Prototyp verwendet wird.
Dies ist die Eigenschaft für jedes Objekt, das ihm Zugriff auf die Object prototype
Eigenschaft gewährt .
Jedes Objekt verfügt standardmäßig über diese Eigenschaft, die sich auf die bezieht, Object Protoype
sofern nichts anderes konfiguriert ist (dh wenn das Objekt __proto__
auf einen anderen Prototyp zeigt).
Ändern der __proto__
Eigenschaft
Diese Eigenschaft kann geändert werden, indem explizit angegeben wird, dass sie sich auf einen anderen Prototyp beziehen soll. Die folgenden Methoden werden verwendet, um dies zu erreichen:
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);
In der Konsole haben Sie Folgendes:

Beachten Sie die __proto__
Eigenschaft und die speak
Methode?
Object.create
verwendet das übergebene Argument, um zum Prototyp zu werden.
new
Stichwort
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
Die __proto__
Eigenschaft von ist auf DogObject
den Prototyp gerichtet. Denken Sie jedoch daran, dass DogObject
der Prototyp ein Objekt ist ( Schlüssel- und Wertepaar ), daher hat er auch eine __proto__
Eigenschaft, die sich auf den globalen Object
Prototyp bezieht .
Diese Technik wird als PROTOTYPENKETTE bezeichnet .
Beachten Sie Folgendes: Der new
Keyword-Ansatz macht dasselbe wie Object.create()
, macht es jedoch nur einfacher, da er einige Dinge automatisch für Sie erledigt.
Und so...
Jedes Objekt in Javascript hat Object
standardmäßig Zugriff auf den Prototyp des Objekts . Bei entsprechender Konfiguration einen weiteren Prototyp zu verwenden, sagen wir prototype2
, dann prototype2
hätte auch Zugriff auf den Prototyp des Objekts standardmäßig und so weiter.
Objekt + Funktionskombination
Sie sind wahrscheinlich verwirrt über die Tatsache, dass DogObject
es sich um eine Funktion ( function DogObject(){}
) handelt, auf deren Eigenschaften mit einer Punktnotation zugegriffen wird . Dies wird als Funktionsobjektkombination bezeichnet .
Wenn Funktionen deklariert werden, erhalten sie standardmäßig viele damit verbundene Eigenschaften. Denken Sie daran, dass Funktionen auch Objekte in JavaScript-Datentypen sind.
Nun, Klasse
JavaScript hat das class
Schlüsselwort in ECMAScript 2015 eingeführt. Dadurch wirkt JavaScript wie eine OOP-Sprache. Aber es ist nur syntatischer Zucker gegenüber der bestehenden Prototyping-Technik. Es setzt sein Prototyping im Hintergrund fort, lässt aber den äußeren Körper wie OOP aussehen. Wir werden uns nun ansehen, wie das möglich ist.
Das folgende Beispiel ist eine allgemeine Verwendung von a class
in 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);
Dies ist das Ergebnis in der Konsole:

The __proto__
references the Animals
prototype (which in turn references the Object
prototype).
From this, we can see that the constructor defines the major features while everything outside the constructor (sing()
and dance()
) are the bonus features (prototypes).
In the background, using the new
keyword approach, the above translates to:
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");
Subclassing
This is a feature in OOP where a class inherits features from a parent class but possesses extra features which the parent doesn't.
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