Was sind Fabrikfunktionen und Konstruktoren?

0 Aktien
0
0
0
0

Einführung

Um das Konzept von Fabrikfunktionen und Konstruktoren zu verstehen, muss man zunächst Funktionen und Objekte verstehen.

Wenn man viele Objekte mit ähnlichen Eigenschaften und Funktionen erstellt, kann das schnell langweilig und eintönig werden. Wir sollten daher das DRY-Prinzip (“Don’t Repeat Yourself”) beachten. Funktionale Muster helfen uns dabei, kürzeren, übersichtlicheren und effizienteren Code zu schreiben. Factory-Funktionen und Konstruktorfunktionen können hier Abhilfe schaffen, aber welche ist die richtige? Schauen wir uns Factory-Funktionen und Konstruktoren genauer an, was sie leisten können und was nicht, und welche Gemeinsamkeiten und Unterschiede bestehen.

Was ist eine Fabrikfunktion?

Eine Fabrikfunktion kann man sich wie eine reale Fabrik vorstellen, die Rohmaterialien verarbeitet und schnell mehrere Produkte herstellt. Fabrikfunktionen hingegen erhalten spezifische Eingaben und verwenden diese, um ein neues Objekt zu erzeugen. Wie können wir das nun konkret nutzen? Wir könnten jedes Objekt einzeln erstellen, aber das würde dauern. Wenn Sie Objekte mit denselben Eigenschaften, aber unterschiedlichen Werten erstellen, kann die Verwendung einer Fabrikfunktion den Prozess beschleunigen.

const car1 = {
make: 'Toyota',
model: 'Tacoma',
year: 2018,
fuelType: 'gas', 
bodyType: 'mid-size pick-up truck',
getFullName() {
return `${this.year} ${this.make} ${this.model}`;
}
}
console.log(car1.getFullName()); // => 2018 Toyota Tacoma

Im obigen Beispiel haben wir ein Objekt erstellt, das eine bestimmte Maschine beschreibt. Nun erstellen wir ein ähnliches Objekt.

const car2 = {
make: 'Tesla', 
model: 'Model S',
year: 2018,
fuelType: 'electric',
bodyType: 'sedan',
getFullName() {
return `${this.year} ${this.make} ${this.model}`;
}
}
console.log(car2.getFullName()); // => 2018 Tesla Model S 

Ich könnte jetzt noch ewig über die Herstellung weiterer Maschinenobjekte reden, aber wer hat schon Zeit dafür, nicht wahr? Mal sehen, wie das als Fabrikfunktion funktioniert.

function createCar (make, model, year, fuelType, bodyType) {
return {
make: make, 
model: model, 
year: year, 
fuelType: fuelType, 
bodyType: bodyType,
getFullName() {
return `${year} ${make} ${model}`;
}
}
}

Wir haben nun eine Factory-Funktion, die neue Objekte für uns erzeugt. Jetzt müssen wir nur noch die Daten übergeben und die Factory-Funktion ihre Arbeit erledigen lassen.

function createCar (make, model, year, fuelType, bodyType) {
return {
make: make, 
model: model, 
year: year, 
fuelType: fuelType, 
bodyType: bodyType,
getFullName() {
return `${year} ${make} ${model}`;
}
}
}
const car1 = createCar('Toyota', 'Tacoma', 2018, 'gas', 'mid-size pick-up truck');
const car2 = createCar('Tesla', 'Model S', 2018, 'electric', 'sedan');
console.log(car1.getFullName()); // => 2018 Toyota Tacoma
console.log(car2.getFullName()); // => 2018 Tesla Model S

Sie können beliebig viele Objekte mithilfe einer Factory-Funktion erstellen, anstatt Code zu wiederholen.

Was sind Konstruktoren?

Die Konstruktorfunktion ist ein weiteres JavaScript-Muster, das Factory-Funktionen sehr ähnlich ist. Im Gegensatz zu Factory-Funktionen gibt die Konstruktorfunktion jedoch kein Objekt zurück. Um verschiedene Objekte mit denselben Eigenschaften zu erzeugen, verwenden wir die Schlüsselwörter “new” und “this”. Sehen wir uns nun an, wie Konstruktorfunktionen visuell funktionieren.

function Car(make, model, year, fuelType, bodyType) {
this.make = make
this.model = model 
this.year = year
this.fuelType = fuelType
this.bodyType = bodyType
this.getFullName = () => {
return `${this.year} ${this.make} ${this.model}`;
}
}

Im obigen Beispiel ähnelt die Konstruktorfunktion einer Factory-Funktion, abgesehen von der Verwendung des Schlüsselworts “this”. ”this” bezieht sich auf die Konstruktorfunktion, die das Instanzobjekt erzeugt hat. Anders ausgedrückt: “this” hat in einer Konstruktorfunktion keinen Wert. Man kann es sich als Basis für das neue Objekt vorstellen.

function Car(make, model, year, fuelType, bodyType) {
this.make = make
this.model = model 
this.year = year
this.fuelType = fuelType
this.bodyType = bodyType
this.getFullName = () => {
return `${this.year} ${this.make} ${this.model}`;
}
}
const car1 = new car('Toyota', 'Tacoma', 2018, 'gas', 'mid-size pick-up truck');
const car2 = new car('Tesla', 'Model S', 2018, 'electric', 'sedan');
console.log(car1.getFullName()); // => 2018 Toyota Tacoma
console.log(car2.getFullName()); // => 2018 Tesla Model S

Um Objekte mithilfe von Konstruktorfunktionen zu erstellen, verwenden wir das Schlüsselwort “new”. Wenn Sie die Anweisung “new” vor einem Funktionsaufruf verwenden, erledigt JavaScript automatisch zwei Dinge für uns: Innerhalb der Funktion wird ein leeres Objekt namens “this” erstellt. Dieses “this”-Objekt wird an die Anweisung zurückgegeben, die die Funktion ursprünglich aufgerufen hat.

function Car(make, model, year, fuelType, bodyType) {
// const this = {};
this.make = make
this.model = model 
this.year = year
this.fuelType = fuelType
this.bodyType = bodyType
this.getFullName = () => {
return `${this.year} ${this.make} ${this.model}`;
}
// return this;
}
const car1 = new car('Toyota', 'Tacoma', 2018, 'gas', 'mid-size pick-up truck');
const car2 = new car('Tesla', 'Model S', 2018, 'electric', 'sedan');
console.log(car1.getFullName()); // => 2018 Toyota Tacoma
console.log(car2.getFullName()); // => 2018 Tesla Model S

Nachlass

Die Vererbung spielt eine wichtige Rolle beim Unterschied zwischen Fabrik- und Builder-Funktionen.

function createCar (make, model, year, fuelType, bodyType) {
return {
make: make, 
model: model, 
year: year, 
fuelType: fuelType, 
bodyType: bodyType,
getFullName() {
return `${year} ${make} ${model}`;
}
}
}
const car1 = createCar('Toyota', 'Tacoma', 2018, 'gas', 'mid-size pick-up truck');
const car2 = createCar('Tesla', 'Model S', 2018, 'electric', 'sedan'); 
car1.getFullName = function() {
return `My ${fuelType} ${bodyType} is a ${year} ${make} ${model}`;
}
console.log(car1.getFullName()); // => My gas mid-size pick-up truck is a 2018 Toyota Tacoma
console.log(car2.getFullName()); // => 2018 Tesla Model S

Kehren wir zum ersten Beispiel einer Factory-Funktion zurück. Was passiert, wenn wir `car1.getFullName()` neu deklarieren möchten? Nun, `car1.getFullName()` und `car2.getFullName()` sind nicht dieselbe Funktion im Speicher. Jedes Objekt erhält eine eigene Kopie der Funktion. Das bedeutet, dass die Funktion beim Erstellen und Zurückgeben eines Objekts dessen Eigenschaften und Werte kopiert und an jedes Objekt bindet, das die Funktion aufruft.

function car(make, model, year, fuelType, bodyType) {
// const this = {};
this.make = make
this.model = model 
this.year = year
this.fuelType = fuelType
this.bodyType = bodyType
this.getFullName = () => {
return `${this.year} ${this.make} ${this.model}`;
}
// return this;
}
const car1 = new car('Toyota', 'Tacoma', 2018, 'gas', 'mid-size pick-up truck');
const car2 = new car('Tesla', 'Model S', 2018, 'electric', 'sedan');
console.log(car1); // => car {make: 'Toyota', model: 'Tacoma' , etc.}

Betrachten wir nun unsere Konstruktorfunktion. Bei ihrer Erstellung besitzt die Konstruktorfunktion einen eigenen Prototyp. Wenn wir mit dem Schlüsselwort “new” ein neues Car-Objekt erzeugen, wird eine Instanz des Typs Car erstellt. Anders ausgedrückt: Der Prototyp von car1 ist vom Typ Car. car1 erbt also vom Car-Konstruktor. Dadurch können wir dem Car-Prototyp Eigenschaften hinzufügen.

Car.prototype.sentence = function() {
return `My ${this.fuelType} ${this.bodyType} is a ${this.year} ${this.make} ${this.model}`;
}
console.log(car1); // => Car {
// make: 'Toyota',
// model: 'Tacoma',
// year: 2018,
// fuelType: 'gas',
// bodyType: 'mid-size pick-up truck',
// getFullName: [Function (anonymous)]
// }

Beachten Sie, dass die Satzfunktion nicht direkt in den Fahrzeugkonfigurator selbst integriert ist.

console.log(Car.prototype); // => { sentence: [Function (anonymous)] }

Doch als wir den Prototyp überprüften, war sie da! Wir können nun auf die neu hinzugefügte Funktion zugreifen.

console.log(car1.sentence()); // => My gas mid-size pick-up truck is a 2018 Toyota Tacoma
console.log(car2.sentence()); // => My electric sedan is a 2018 Tesla Model S

Nachdem wir nun die Funktionsweise der einzelnen Operationen kennen, stellt sich die Frage: Welche sollten wir verwenden? Beide können zum gleichen Ergebnis führen. Konstruktoren eignen sich hervorragend, um Eigenschaften zu Objekten hinzuzufügen oder zu entfernen, die vom Konstruktor erben. Factory-Funktionen sind jedoch oft leichter verständlich, da sie im Grunde genommen einfach Funktionen sind. Bei Factory-Funktionen ist das Schlüsselwort “new” nicht erforderlich. Dank der Möglichkeiten von Closures bieten sie mehr Flexibilität. Damit lässt sich beispielsweise “Datenschutz” realisieren. Betrachten wir ein weiteres Beispiel, das dies verdeutlicht.

function createCar(make, model, year) {
return {
getFullName() {
return `${year} ${make} ${model}`;
}
}
}
const car1 = createCar('Toyota', 'Tacoma', 2018); 
console.log(car1.getFullName()); // => 2018 Toyota Tacoma
console.log(car1.make); // => undefined
console.log(car1); // => { getFullName: [Function: getFullName] }

Ergebnis

Im Grunde genommen ist das Wichtigste beim Schreiben eigenen Codes, dass daran nichts grundsätzlich falsch sein kann. Es gibt gute Möglichkeiten, den Code sauber und kurz zu halten. Verwenden Sie Factory- und Konstruktorfunktionen, wo immer es Ihnen sinnvoll erscheint.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Das könnte Ihnen auch gefallen