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    

Artikel empfehlen

So erhalten Sie USB-Scannerdaten mit js

In diesem Artikel wird der spezifische Prozess zu...

Zwei Möglichkeiten zum Starten des Linux-Bootdienstes

Inhaltsverzeichnis rc.local-Methode chkconfig-Met...

Vue implementiert Drag & Drop oder Klicken zum Hochladen von Bildern

In diesem Artikel wird der spezifische Code von V...

Implementierungsbeispiel eines Videoplayers basierend auf Vue

Wenn der vorhandene Videoplayer die Anforderungen...

Detaillierte Erläuterung der Destrukturierungszuweisung von JS ES6-Variablen

Inhaltsverzeichnis 1. Was ist Dekonstruktion? 2. ...

WebStorm kann die Lösung der Vue3-kombinierten API nicht korrekt identifizieren

1 Problembeschreibung Die kombinierte API von Vue...

In der HTML-Tabelle wird nur der äußere Rand der Tabelle angezeigt

Ich möchte eine Frage stellen. Ich habe in Dreamw...

Untersuchung der Wirkung der durch JS realisierten Seitenseitenleiste

Inhaltsverzeichnis Entdecken Sie: Anwendung von D...

Konfigurieren Sie VIM als C++-Entwicklungseditor in Ubuntu

1. Kopieren Sie die Konfigurationsdatei in die Be...

So legen Sie Listenstilattribute in CSS fest (lesen Sie einfach diesen Artikel)

Eigenschaften des Listenstils Es gibt 2 Arten von...

So installieren und implementieren Sie Zabbix 5.0 für Nginx

Inhaltsverzeichnis Experimentelle Umgebung Instal...

Zusammenfassung der Verwendung von MySQL Online DDL gh-ost

Hintergrund: Als DBA werden die meisten DDL-Änder...