Welche Szenarien sind für JS-Pfeilfunktionen nicht geeignet?

Welche Szenarien sind für JS-Pfeilfunktionen nicht geeignet?

Überblick

Nach all diesen Jahren hat ES6 die Benutzerfreundlichkeit von JS auf ein neues Niveau gehoben: Pfeilfunktionen, Klassen usw., die großartig sind.

Pfeilfunktionen sind eine der wertvollsten neuen Funktionen und es gibt viele gute Artikel, die ihre Kontexttransparenz und kurze Syntax beschreiben.

Aber jede Transaktion hat zwei Seiten. Neue Funktionen sorgen häufig für Verwirrung. Eine dieser Verwirrungen ist die falsche Verwendung von Pfeilfunktionen. Dieser Artikel behandelt einige Szenarien, in denen Sie Pfeilfunktionen zugunsten guter alter Funktionsausdrücke oder der neueren Kurzsyntax umgehen sollten. Achten Sie beim Kürzen Ihres Codes auch darauf, dass dies die Lesbarkeit des Codes beeinträchtigt.

Definieren von Methoden für ein Objekt

In JavaScript sind Methoden Funktionen, die als Eigenschaften eines Objekts gespeichert sind. Beim Aufruf der Methode wird hiermit auf das Objekt verwiesen, zu dem die Methode gehört.

Objektliterale

Da Pfeilfunktionen eine kurze Syntax haben, ist es verlockend, sie zum Definieren von Methoden zu verwenden. Versuchen wir es:

const berechnen = {
  Array: [1, 2, 3],
  Summe: () => {
    console.log(dies === Fenster); // => wahr
    returniere this.array.reduce((Ergebnis, Element) => Ergebnis + Element);
  }
};
console.log(dies === Fenster); // => wahr
// Wirft „TypeError: Kann Eigenschaft ‚reduce‘ von undefined nicht lesen“
berechne.Summe();

Die Methode calculate.sum wird mithilfe einer Pfeilfunktion definiert. Beim Aufruf löst calculate.sum() jedoch einen TypeError aus, da this.array nicht definiert ist.

Wenn die Methode sum() für das Berechnungsobjekt aufgerufen wird, ist der Kontext immer noch das Fenster. Dies liegt daran, dass die Pfeilfunktion den Kontext lexikalisch an das Fensterobjekt bindet.

Die Ausführung von this.array entspricht window.array, das nicht definiert ist.

Die Lösung besteht darin, zum Definieren der Methode einen regulären Funktionsausdruck zu verwenden. Dies wird zum Aufrufzeitpunkt bestimmt, nicht durch den umschließenden Kontext. Schauen wir uns die korrigierte Version an:

const berechnen = {  
  Array: [1, 2, 3],
  Summe() {
    console.log(dies === berechnen); // => wahr
    returniere this.array.reduce((Ergebnis, Element) => Ergebnis + Element);
  }
};
berechne.Summe(); // => 6

Da „sum“ eine reguläre Funktion ist, ist dies das Berechnungsobjekt, wenn Sie „calculate.sum()“ aufrufen. this.array ist eine Array-Referenz, daher wird die Summe der Elemente korrekt berechnet: 6.

Objektprototyp

Für die Definition von Methoden für Prototypobjekte gelten die gleichen Regeln. Verwenden Sie eine Pfeilfunktion, um die Methode sayCatName zu definieren. Diese zeigt auf das Fenster

Funktion MeineKatze(Name) {
  dies.catName = Name;
}
MeineKatze.prototype.sayCatName = () => {
  console.log(dies === Fenster); // => wahr
  gib diesen.Katzennamen zurück;
};
const cat = neue MeineKatze('Mew');
cat.sayCatName(); // => undefiniert

Verwenden der früheren Methode zum Definieren eines Funktionsausdrucks:

Funktion MeineKatze(Name) {
  dies.catName = Name;
}
MeineKatze.prototype.sayCatName = function() {
  konsole.log(dies === Katze); // => wahr
  gib diesen.Katzennamen zurück;
};
const cat = neue MeineKatze('Mew');
cat.sayCatName(); // => 'Miau'

Die reguläre Funktion sayCatName ändert den Kontext zum Katzenobjekt, wenn sie als Methode aufgerufen wird: cat.sayCatName().

Dynamische Kontext-Callback-Funktion

Dies ist eine leistungsstarke Funktion in JS, die eine Änderung des Kontexts je nach Aufruf einer Funktion ermöglicht. Normalerweise ist der Kontext das Zielobjekt, bei dem der Aufruf erfolgt, wodurch der Code natürlicher wirkt, als ob das, was mit diesem Objekt geschieht, klar wäre.

Pfeilfunktionen binden den Kontext jedoch statisch an die Deklaration und können nicht dynamisch gestaltet werden. Dieser Ansatz hat jedoch sowohl gute als auch schlechte Seiten und manchmal benötigen wir eine dynamische Bindung.

Das Anhängen von Ereignis-Listenern an DOM-Elemente ist eine gängige Aufgabe bei der clientseitigen Programmierung. Das Ereignis löst die Handlerfunktion aus und verwendet diese als Zielelement. Die Verwendung einer Pfeilfunktion ist hier nicht flexibel genug.

Das folgende Beispiel versucht, eine Pfeilfunktion für einen solchen Handler zu verwenden:

const button = document.getElementById('meinButton');
button.addEventListener('klicken', () => {
  console.log(dies === Fenster); // => wahr
  this.innerhtml = 'Schaltfläche angeklickt';
});

Im globalen Kontext bezieht sich dies auf Fenster. Wenn ein Klickereignis auftritt, versucht der Browser, die Handlerfunktion unter Verwendung des Schaltflächenkontexts aufzurufen, aber die Pfeilfunktion ändert ihren vordefinierten Kontext nicht. this.innerhtml ist gleichwertig mit window.innerHTML und hat keine Bedeutung.

Es muss ein Funktionsausdruck verwendet werden, der es erlaubt, dies je nach Zielelement zu ändern:

const button = document.getElementById('meinButton');
button.addEventListener('klicken', function() {
  console.log(diese === Schaltfläche); // => wahr
  this.innerHTML = 'Schaltfläche angeklickt';
});

Wenn der Benutzer auf die Schaltfläche klickt, zeigt dies in der Handlerfunktion auf die Schaltfläche. Daher diese Frage. innerHTML = „Schaltfläche angeklickt“ ändert den Schaltflächentext korrekt, um den angeklickten Status wiederzugeben.

Aufrufen des Konstruktors

Dies ist in einem Konstruktoraufruf das neu erstellte Objekt. Wenn new MyFunction() ausgeführt wird, ist der Kontext des Konstruktors MyFunction ein neues Objekt: diese Instanz von MyFunction === true.

Beachten Sie, dass Pfeilfunktionen nicht als Konstruktoren verwendet werden können. JavaScript verhindert dies implizit, indem es eine Ausnahme auslöst.

Unabhängig davon wird dies aus dem umschließenden Kontext und nicht aus dem neu erstellten Objekt festgelegt. Mit anderen Worten: Der Aufruf des Pfeilfunktionskonstruktors ist nicht sinnvoll und mehrdeutig.

Mal sehen, was passiert, wenn wir Folgendes versuchen:

const Message = (Text) => {
  dieser.text = Text;
};
// Wirft „TypeError: Nachricht ist kein Konstruktor“
const helloMessage = neue Nachricht('Hallo Welt!');

Beim Ausführen einer neuen Nachricht (,Hallo Welt!‘), wobei es sich bei Nachricht um eine Pfeilfunktion handelt, gibt JavaScript einen TypeError-Fehler aus, da Nachricht nicht als Konstruktor verwendet werden kann.

Das obige Beispiel kann durch die Verwendung eines Funktionsausdrucks behoben werden. Dies ist die korrekte Art, einen Konstruktor (einschließlich einer Funktionsdeklaration) zu erstellen:

const Nachricht = Funktion(Text) {
  dieser.text = Text;
};
const helloMessage = neue Nachricht('Hallo Welt!');

Kurzschriftsyntax

Pfeilfunktionen haben die nette Eigenschaft, dass sie Parameterklammern () und Blockklammern {} weglassen und zurückkehren können, wenn der Funktionskörper nur eine Anweisung hat. Dies hilft beim Schreiben sehr kurzer Funktionen.

Der Universitätsprofessor für Programmierung des ursprünglichen Autors gab den Studenten eine interessante Aufgabe: Schreiben Sie die kürzeste Funktion, um die Länge einer Zeichenfolge in der Sprache C zu berechnen. Dies ist eine großartige Möglichkeit, eine neue Sprache zu lernen und zu erkunden.

In realen Anwendungen lesen jedoch viele Entwickler den Code. Die kürzeste Syntax ist nicht immer geeignet, um Ihren Kollegen sofort zu helfen, zu verstehen, was die Methode macht.

Ab einem bestimmten Punkt sind Kurzfunktionen schwer zu lesen. Versuchen Sie daher, sie nicht zu häufig zu verwenden. Lassen Sie mich Ihnen ein Beispiel zeigen.

const multiplizieren = (a, b) => b === undefiniert? b => a * b: a * b;
const double = Multiplikation(2);
doppelt(3); // => 6
multiplizieren(2, 3); // => 6

„multiplizieren“ gibt das Ergebnis der Multiplikation zweier Zahlen oder einen an das erste Argument gebundenen Abschluss für spätere Multiplikationsoperationen zurück.

Die Funktion funktioniert einwandfrei und scheint kurz zu sein. Aber von Anfang an war es schwer zu verstehen, was es bewirkte.

Um es lesbarer zu machen, können Sie die optionalen geschweiften Klammern und die Return-Anweisung aus der Pfeilfunktion wiederherstellen oder eine reguläre Funktion verwenden:

Funktion multiplizieren(a, b) {
  wenn (b === undefiniert) {
    Rückgabefunktion (b) {
      gib a * b zurück;
    }
  }
  gib a * b zurück;
}
const double = Multiplikation(2);
doppelt(3); // => 6
multiplizieren(2, 3); // => 6

Es ist gut, ein Gleichgewicht zwischen Kürze und Ausführlichkeit zu finden, das den Code intuitiver macht.

Zusammenfassen

Es besteht kein Zweifel, dass Pfeilfunktionen eine großartige Ergänzung sind. Bei korrekter Verwendung erleichtert es die Verwendung von .bind() oder den Versuch, den Kontext an Stellen zu erfassen, an denen dies zuvor erforderlich war. Außerdem vereinfacht es den Code.

Vorteile in manchen Situationen können in anderen Nachteile mit sich bringen. Pfeilfunktionen können nicht verwendet werden, wenn ein dynamischer Kontext erforderlich ist: Definieren von Methoden, Erstellen von Objekten mit Konstruktoren, Abrufen des Ziels daraus bei der Ereignisbehandlung.

Oben sind die Einzelheiten, warum JS nicht für Pfeilfunktionen geeignet ist. Weitere Informationen zu JS finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM!

Das könnte Sie auch interessieren:
  • Tipps zum Schreiben besserer Bedingungen und Übereinstimmungsbedingungen in JavaScript (Zusammenfassung)
  • Detaillierte Erklärung dieser Zeigerfunktion in JS
  • Eigenschaften von JavaScript-Pfeilfunktionen und Unterschiede zu normalen Funktionen
  • Detaillierte Erklärung des Unterschieds zwischen Pfeilfunktionen und normalen Funktionen in JavaScript
  • In welchen Szenarien in JavaScript können Pfeilfunktionen nicht verwendet werden?
  • Einführung in bedingte Zugriffsattribute und Pfeilfunktionen in JavaScript

<<:  Installieren und konfigurieren Sie MySQL 5.7 unter CentOS 7

>>:  Detaillierte Erläuterung der Linux-Befehle „Datei überschreiben“ und „Datei anhängen“

Artikel empfehlen

Beispielcode zur Implementierung einer Upload-Komponente mit Vue3

Inhaltsverzeichnis Allgemeine Entwicklung von Upl...

Acht gängige SQL-Verwendungsbeispiele in MySQL

Vorwort MySQL setzte auch 2016 seinen starken Wac...

Einfache Schritte zum Kapseln von Komponenten in Vue-Projekten

Inhaltsverzeichnis Vorwort So kapseln Sie eine To...

Installieren Sie Ubuntu 18 ohne USB-Laufwerk unter Windows 10 mit EasyUEFI

1. BIOS überprüfen Überprüfen Sie zunächst, in we...

Detailliertes Tutorial zur Installation von Anaconda3 auf Ubuntu 18.04

Anaconda bezeichnet eine Open-Source-Python-Distr...

36 Prinzipien der MySQL-Datenbankentwicklung (Zusammenfassung)

Vorwort Diese Prinzipien sind aus tatsächlichen K...

Details zur Verwendung von Bimface in Vue

Inhaltsverzeichnis 1. Installieren Sie das Vue-Ge...

So löschen Sie node_modules und installieren es neu

Inhaltsverzeichnis Schritt 1: Installieren Sie no...

CSS-Pickup-Pfeile, Kataloge, Icons Implementierungscode

1. Verschiedene CSS-Symbole Es gibt drei Möglichk...