Heim  >  Artikel  >  Web-Frontend  >  Detaillierte Erläuterung der Klassen-, Konstruktor- und Factory-Funktionen in Javascript

Detaillierte Erläuterung der Klassen-, Konstruktor- und Factory-Funktionen in Javascript

小云云
小云云Original
2017-12-21 14:40:411911Durchsuche

In der ES6-Ära haben wir mehr Möglichkeiten, Objekte zu erstellen. Wir können verschiedene Methoden wählen, um sie in verschiedenen Szenarien zu erstellen. Derzeit gibt es drei Hauptmethoden zum Erstellen von Objekten: das Klassenschlüsselwort, den Konstruktor und die Factory-Funktion. Sie sind alle Mittel zum Erstellen von Objekten, aber sie sind unterschiedlich. Während der täglichen Entwicklung müssen Sie auch auf der Grundlage dieser Unterschiede auswählen. Dieser Artikel stellt hauptsächlich die detaillierte Erklärung von Klassen, Konstruktoren und Factory-Funktionen in Javascript vor. Freunde, die sie benötigen, können darauf zurückgreifen.

Schauen wir uns zunächst an, wie diese drei Methoden aussehen


// class 关键字,ES6新特性
class ClassCar {
 drive () {
  console.log('Vroom!');
 }
}
const car1 = new ClassCar();
console.log(car1.drive());
// 构造函数
function ConstructorCar () {}
ConstructorCar.prototype.drive = function () {
 console.log('Vroom!');
};
const car2 = new ConstructorCar();
console.log(car2.drive());
// 工厂函数
const proto = {
 drive () {
  console.log('Vroom!');
 }
};
function factoryCar () {
 return Object.create(proto);
}
const car3 = factoryCar();
console.log(car3.drive());

Diese Methoden basieren alle auf der Prototyperstellung und werden in der Implementierung unterstützt von privaten Variablen in Konstruktorfunktionen. Mit anderen Worten: Diese Funktionen haben größtenteils die gleichen Eigenschaften und sind in vielen Szenarien sogar gleichwertig.

In Javascript kann jede Funktion ein neues Objekt zurückgeben. Wenn es sich nicht um einen Konstruktor oder eine Klasse handelt, wird sie als Factory-Funktion bezeichnet.

ES6-Klassen sind eigentlich Syntaxzucker für Konstruktoren (zumindest ist dies in dieser Phase so implementiert), daher gilt alles, was als nächstes besprochen wird, für Konstruktoren und ES6-Klassen:


class Foo {}
console.log(typeof Foo); // function

Die Vorteile von Konstruktoren und ES6-Klassen

  • Die meisten Bücher lehren Sie, Klassen und Konstruktoren zu verwenden

  • 'this' zeigt auf das neue Objekt.

  • Einige Leute mögen die Lesbarkeit des neuen Schlüsselworts

  • Es kann einige kleine Details geben, aber wenn es während der Entwicklung keine Probleme gibt Prozess, machen Sie sich nicht zu viele Sorgen.

Nachteile von Konstruktoren und ES6-Klassen

1 Sie benötigen das neue Schlüsselwort

In ES6 müssen sowohl Konstruktoren als auch Klassen das Schlüsselwort new haben.


function Foo() {
 if (!(this instanceof Foo)) { return new Foo(); }
}

Wenn Sie in ES6 versuchen, eine Klassenfunktion ohne das Schlüsselwort new aufzurufen, wird eine Aufgabe ausgelöst. Wenn Sie eines ohne das Schlüsselwort new möchten, können Sie es nur mit einer Factory-Funktion umschließen.

2. Details während des Instanziierungsprozesses werden der externen API angezeigt

Alle Aufrufe stehen in engem Zusammenhang mit der Implementierung des Konstruktors. Wenn Sie während des Konstruktionsprozesses selbst einige Änderungen vornehmen müssen und Füße, das ist eine sehr lästige Sache.

3. Der Konstruktor entspricht nicht der Open/Closed-Regel

Aufgrund der detaillierten Verarbeitung des neuen Schlüsselworts verstößt der Konstruktor gegen die Open/Closed-Regel: Die API sollte offen sein für Erweiterung und vermeiden Sie Änderungen.

Ich habe einmal in Frage gestellt, dass Klassen und Factory-Funktionen so ähnlich sind, dass ein Upgrade der Klassenfunktion auf eine Factory-Funktion keine Auswirkungen haben wird, in JavaScript jedoch schon.

Wenn Sie anfangen, Konstruktoren oder Klassen zu schreiben, aber im weiteren Verlauf feststellen, dass Sie die Flexibilität der Factory-Funktion benötigen, können Sie zu diesem Zeitpunkt nicht einfach die Funktion ändern und weggehen.

Leider sind Sie ein JavaScript-Programmierer und die Umwandlung eines Konstruktors in eine Factory-Funktion ist ein großer Vorgang:


// 原来的实现:
// class Car {
//  drive () {
//   console.log('Vroom!');
//  }
// }
// const AutoMaker = { Car };
// 工厂函数改变的实现:
const AutoMaker = {
 Car (bundle) {
  return Object.create(this.bundle[bundle]);
 },
 bundle: {
  premium: {
   drive () {
    console.log('Vrooom!');
   },
   getOptions: function () {
    return ['leather', 'wood', 'pearl'];
   }
  }
 }
};
// 期望中的用法是:
const newCar = AutoMaker.Car('premium');
newCar.drive(); // 'Vrooom!'
// 但是因为他是一个库
// 许多地方依然这样用:
const oldCar = new AutoMaker.Car();
// 如此就会导致:
// TypeError: Cannot read property 'undefined' of
// undefined at new AutoMaker.Car

Im obigen Beispiel: Wir beginnen mit einer Klasse und wandeln sie schließlich in eine Factory-Funktion um, die Objekte basierend auf einem bestimmten Prototyp erstellen kann. Eine solche Funktion kann häufig zur Schnittstellenabstraktion und zur Anpassung spezieller Anforderungen verwendet werden.

4. Verwenden Sie Konstruktoren, um Instanzen eine Möglichkeit zu geben

Der Unterschied zwischen Konstruktoren und Factory-Funktionen ist der Instanzen-Operator, um die Korrektheit ihres Codes sicherzustellen. Aber um ehrlich zu sein, ist dies sehr problematisch und es wird empfohlen, die Verwendung von Instanzen zu vermeiden.

instanceof kann liegen.


// instanceof 是一个原型链检查
// 不是一个类型检查
// 这意味着这个检查是取决于执行上下文的,
// 当原型被动态的重新关联,
// 你就会得到这样令人费解的情况
function foo() {}
const bar = { a: 'a'};
foo.prototype = bar;
// bar是一个foo的实例吗,显示不是
console.log(bar instanceof foo); // false
// 上面我们看到了,他的确不是一个foo实例
// baz 显然也不是一个foo的实例,对吧?
const baz = Object.create(bar);
// ...不对.
console.log(baz instanceof foo); // true. oops.

instanceof prüft nicht wie andere stark typisierte Sprachen, sondern lediglich das Objekt in der Prototypenkette.

In einigen Ausführungskontexten ist es ungültig, beispielsweise wenn Sie Constructor.prototype ändern.

Ein weiteres Beispiel ist, dass Sie mit einem Konstruktor oder einer Klasse beginnen und diese dann in ein anderes Objekt erweitern, genau wie in der obigen Situation, in der Sie sie in eine Factory-Funktion umschreiben. Zu diesem Zeitpunkt wird es auch Probleme mit der Instanz von geben.

Alles in allem ist „Instanceof“ eine weitere große Änderung bei Konstruktor- und Factory-Funktionsaufrufen.

Vorteile der Verwendung von Klassen

  • Ein praktisches, eigenständiges Schlüsselwort

  • Die einzige maßgebliche Möglichkeit, Klassen in JavaScript zu implementieren.

  • Es ist eine gute Erfahrung für andere Entwickler, die Erfahrung in der Entwicklung von Klassensprachen haben.

Nachteile der Verwendung von Klassen

Alle Nachteile von Konstruktoren, plus:

Die Verwendung des Schlüsselworts „extens“ zum Erstellen einer problematischen Klasse für Benutzer ist ein großes Problem Verlockung.
Die hierarchische Vererbung von Klassen verursacht viele bekannte Probleme, darunter fragmentierte Basisklassen (die Basisklasse wird durch Vererbung zerstört), Gorilla-Bananen-Probleme (Objekte werden mit komplexen Kontexten vermischt) und Duplizierung durch Notwendigkeit (Klassen werden diversifiziert vererbt). müssen von Zeit zu Zeit geändert werden) und so weiter.

Auch wenn Sie mit den anderen beiden Methoden möglicherweise ebenfalls auf diese Probleme stoßen, führt Sie die Umgebung bei Verwendung des Schlüsselworts „extend“ auf diesen Weg. Mit anderen Worten: Es führt Sie dazu, Code mit unflexiblen Beziehungen zu schreiben, statt wiederverwendbareren Code.

Vorteile der Verwendung von Factory-Funktionen

Factory-Funktionen sind flexibler als Klassen und Konstruktoren und führen nicht zu Fehlern. Sie werden dadurch auch nicht in einer tiefen Vererbungskette stecken bleiben. Sie können viele Methoden verwenden, um die Vererbung zu simulieren

1. Geben Sie jedes Objekt mit einem beliebigen Prototyp zurück

Sie können beispielsweise verschiedene Instanzen eines Mediaplayers über dieselbe Implementierung erstellen. Instanzen können für verschiedene erstellt werden Medienformate, die Verwendung verschiedener APIs oder eine Ereignisbibliothek können für DOM-Ereignisse oder WS-Ereignisse sein.

Die Factory-Funktion kann Objekte auch über den Ausführungskontext instanziieren, was vom Objektpool und einem flexibleren Vererbungsmodell profitieren kann.

2. Machen Sie sich keine Sorgen über komplexes Refactoring

Sie werden nie die Notwendigkeit haben, Factory-Funktionen in Konstruktoren umzuwandeln, daher ist kein Refactoring erforderlich.

3. Nein neu

Sie verwenden nicht das Schlüsselwort new, um ein neues Objekt zu erstellen, Sie können diesen Prozess selbst meistern.

4. Standardisieren Sie dieses Verhalten

Dies ist das, mit dem Sie vertraut sind, und Sie können es verwenden, um das übergeordnete Objekt abzurufen. In „player.create()“ zeigt dies beispielsweise auf den Spieler, und andere können auch durch „Aufruf“ und „Anwenden“ gebunden werden.

5. Keine Probleme mit der Instanz von

6. Manche Leute mögen die Lesbarkeit und Intuitivität, direkt ohne Neues zu schreiben.

Nachteile von Factory-Funktionen

  • verarbeitet Prototypen nicht automatisch, und Factory-Funktionsprototypen haben keinen Einfluss auf die Prototypenkette .

  • dies verweist nicht automatisch auf das neue Objekt in der Factory-Funktion.

  • Es kann einige kleine Unterschiede im Detail geben, aber wenn es während des Entwicklungsprozesses keine Probleme gibt, machen Sie sich keine allzu großen Sorgen.

Fazit

Klasse mag meiner Meinung nach ein praktisches Schlüsselwort sein, aber es kann es nicht verbergen. Wird ahnungslos führen Benutzer in die Grube der Vererbung. Ein weiteres Risiko besteht darin, dass Sie in Zukunft Fabrikfunktionen nutzen möchten und sehr große Änderungen vornehmen müssen.

Wenn Sie in einem relativ großen Team arbeiten und eine öffentliche API ändern möchten, können Sie in Code eingreifen, auf den Sie keinen Zugriff haben, sodass Sie die Auswirkungen geänderter Funktionen nicht ignorieren können .

Eines der großartigen Dinge am Fabrikmuster ist, dass es nicht nur leistungsfähiger und flexibler ist, sondern auch das gesamte Team dazu ermutigt, die API einfacher, sicherer und leichter zu machen.

Verwandte Empfehlungen:

Ausführliche Einführung dazu und Rückgabe in JavaScript-Konstruktoren

So verwenden Sie Factory-Muster und -Konstruktoren in JavaScript zum Erstellen von Objekten?

Detaillierte Beispiele für den Unterschied zwischen Javascript-Funktionsliteralen und Function()-Konstruktoren

So verwenden Sie den Factory-Modus, den Konstruktormodus und den Prototypenmodus in Javascript Detaillierte Erklärung zum Erstellen von Objektinstanzen

Detaillierte Erklärung von Ausdrücken und Konstruktoren im grundlegenden JavaScript-Tutorial

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der Klassen-, Konstruktor- und Factory-Funktionen in Javascript. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn