Class vs Factory-Funktion: Erkundung des Weges nach vorne

Discover Functional JavaScript wurde von BookAuthority als eines der besten neuen funktionalen Programmierbücher ausgezeichnet !

ECMAScript 2015 (auch bekannt als ES6) enthält die classSyntax. Daher haben wir jetzt zwei konkurrierende Muster zum Erstellen von Objekten. Um sie zu vergleichen, erstelle ich dieselbe Objektdefinition (TodoModel) wie eine Klasse.und dann als Werksfunktion.

TodoModel als Klasse

class TodoModel { constructor(){ this.todos = []; this.lastChange = null; } addToPrivateList(){ console.log("addToPrivateList"); } add() { console.log("add"); } reload(){} }

TodoModel als Factory-Funktion

function TodoModel(){ var todos = []; var lastChange = null; function addToPrivateList(){ console.log("addToPrivateList"); } function add() { console.log("add"); } function reload(){} return Object.freeze({ add, reload }); }

Verkapselung

Als erstes stellen wir fest, dass alle Mitglieder, Felder und Methoden eines Klassenobjekts öffentlich sind.

var todoModel = new TodoModel(); console.log(todoModel.todos); //[] console.log(todoModel.lastChange) //null todoModel.addToPrivateList(); //addToPrivateList

Das Fehlen einer Kapselung kann zu Sicherheitsproblemen führen. Nehmen Sie das Beispiel eines globalen Objekts, das direkt über die Entwicklerkonsole geändert werden kann.

Bei Verwendung der Factory-Funktion sind nur die von uns bereitgestellten Methoden öffentlich, alles andere ist gekapselt.

var todoModel = TodoModel(); console.log(todoModel.todos); //undefined console.log(todoModel.lastChange) //undefined todoModel.addToPrivateList(); //taskModel.addToPrivateList is not a function

Dies

thisBei der Verwendung von Klassen treten immer noch Kontextprobleme auf. Verliert beispielsweise thisden Kontext in verschachtelten Funktionen. Es ist nicht nur ärgerlich beim Codieren, sondern auch eine ständige Fehlerquelle.

class TodoModel { constructor(){ this.todos = []; } reload(){ setTimeout(function log() { console.log(this.todos); //undefined }, 0); } } todoModel.reload(); //undefined

oder thisverliert den Kontext, wenn die Methode wie bei einem DOM-Ereignis als Rückruf verwendet wird.

$("#btn").click(todoModel.reload); //undefined

Es gibt keine derartigen Probleme bei der Verwendung einer Factory-Funktion, da diese überhaupt nicht verwendet wird this.

function TodoModel(){ var todos = []; function reload(){ setTimeout(function log() { console.log(todos); //[] }, 0); } } todoModel.reload(); //[] $("#btn").click(todoModel.reload); //[]

diese und Pfeilfunktion

Die Pfeilfunktion löst teilweise die verlorenen thisKontextprobleme in Klassen, schafft jedoch gleichzeitig ein neues Problem:

  • this verliert in verschachtelten Funktionen nicht mehr den Kontext
  • this verliert den Kontext, wenn die Methode als Rückruf verwendet wird
  • Die Pfeilfunktion fördert die Verwendung anonymer Funktionen

Ich habe die TodoModelVerwendung der Pfeilfunktion überarbeitet. Es ist wichtig zu beachten, dass wir beim Umgestalten der Pfeilfunktion etwas verlieren können, das für die Lesbarkeit sehr wichtig ist, den Funktionsnamen. Schauen Sie sich zum Beispiel an:

//using function name to express intent setTimeout(function renderTodosForReview() { /* code */ }, 0); //versus using an anonymous function setTimeout(() => { /* code */ }, 0);

Discover Functional JavaScript wurde als einer derbeste neue funktionale Programmierbücher von BookAuthority !

Weitere Informationen zum Anwenden funktionaler Programmiertechniken in React finden Sie unter Functional React .

Lernen Sie funktionale Reaktionen projektbasiert mit funktionaler Architektur mit React und Redux .

Auf Twitter folgen