JavaScript Arrow-Funktionen
Erfahren Sie, wie JavaScript-Arrow-Funktionen funktionieren: lexikalisches this, kein eigenes arguments oder super, warum sie keine Konstruktoren sein können.
Einführung in JavaScript Arrow-Funktionen
Arrow-Funktionen, eingeführt in ES6 (ECMAScript 2015), sind mittlerweile ein zentrales Merkmal von JavaScript und bieten eine einfachere Möglichkeit, Funktionsausdrücke zu schreiben. Sie sind besonders beliebt, weil sie den Code übersichtlicher machen und häufige Probleme mit dem Schlüsselwort this lösen.
Diese Seite geht über die Syntax hinaus (die in Arrow-Funktionen, die Grundlagen behandelt wird) und erklärt warum Arrow-Funktionen sich so verhalten, wie sie es tun. Kurz gesagt: Eine Arrow-Funktion hat keine eigenen Bindungen. Sie erhält kein eigenes this, kein eigenes arguments, kein eigenes super und keine [[Construct]]-Methode. Wenn Sie innerhalb einer Arrow-Funktion auf eines dieser Elemente verweisen, sucht JavaScript es im umgebenden (lexikalischen) Gültigkeitsbereich – genau wie bei einer gewöhnlichen Variablen. Nahezu jede Besonderheit und jeder Vorteil von Arrow-Funktionen ergibt sich aus dieser einen Regel.
Arrow-Funktionen definieren
Arrow-Funktionen ermöglichen eine kürzere Syntax im Vergleich zu traditionellen Funktionsausdrücken. Hier ist ein grundlegender Vergleich zur Veranschaulichung:
Die Arrow-Funktion ist nicht nur kürzer, sondern macht bei einem einzelnen Ausdruck auch das Schlüsselwort function und die geschweiften Klammern überflüssig.
Syntaxvarianten
Arrow-Funktionen können je nach Anzahl der Parameter und Komplexität des Funktionskörpers in verschiedenen Formen geschrieben werden:
- Keine Parameter: Leere Klammern verwenden:
- Einzelner Parameter: Klammern sind optional:
- Mehrere Parameter: Klammern sind erforderlich:
- Mehrere Zeilen: Geschweifte Klammern und ein explizites
returnverwenden (wenn ein Wert zurückgegeben wird):
Arrow-Funktionen haben kein eigenes this
Die wichtigste Eigenschaft von Arrow-Funktionen ist, dass sie kein eigenes this erhalten. Eine reguläre Funktion bestimmt ihr this zur Aufrufzeit basierend darauf, wie sie aufgerufen wird (behandelt in Objektmethoden, „this"). Eine Arrow-Funktion ignoriert das und liest this aus dem Bereich, in dem sie definiert wurde – das nennt man lexikalisches this.
Genau das ist gewünscht, wenn eine Arrow-Funktion als Callback ausgeführt wird. Eine Methode, die ihr this in einem gewöhnlichen Callback verliert, behält es in einer Arrow-Funktion:
Ersetzen Sie die Arrow-Funktion durch ein reguläres function(member) { ... }, wird this innerhalb von forEach zu undefined und wirft Cannot read properties of undefined. Vor Arrow-Funktionen halfen Entwickler sich mit const self = this; oder .bind(this) — siehe Funktionsbindung. Arrow-Funktionen machen diese Tricks überflüssig.
Dieselbe lexikalische Regel löst das klassische Timer-Problem, bei dem ein Callback losgelöst von seinem Objekt ausgeführt wird:
Da this lexikalisch festgelegt ist, kann es nicht geändert werden. Das Aufrufen von .call(), .apply() oder .bind() auf einer Arrow-Funktion hat keinen Effekt auf this – die Bindung wird ignoriert:
Arrow-Funktionen haben kein arguments
Arrow-Funktionen haben auch kein eigenes arguments-object. Eine Referenz auf arguments innerhalb einer Arrow-Funktion greift auf die umschließende Funktion zurück – was für Wrapper und Dekoratoren sehr praktisch ist:
Wenn Sie tatsächlich die Argumente der Arrow-Funktion selbst benötigen, verwenden Sie Rest-Parameter (...args), die überall funktionieren:
Arrow-Funktionen sind nicht konstruierbar
Da eine Arrow-Funktion keine interne [[Construct]]-Methode und keine prototype-Eigenschaft hat, kann sie nicht mit dem new-Operator verwendet werden:
Aus demselben Grund können Arrow-Funktionen nicht mit super auf eine übergeordnete Klasse verweisen und werden daher nie als Klassenkonstruktoren oder Klassenmethoden verwendet, die auf super angewiesen sind.
Wann Arrow-Funktionen nicht verwendet werden sollten
Lexikalisches this ist in Callbacks ideal, aber an einigen häufigen Stellen falsch. Greifen Sie auf eine reguläre Funktion zurück, wenn die Funktion ihr eigenes dynamisches this benötigt.
Objektmethoden
Wenn eine Funktion die Methode eines Objekts ist, soll this normalerweise auf dieses Objekt zeigen. Eine Arrow-Funktion nimmt this stattdessen aus dem äußeren Gültigkeitsbereich (oft dem Modul- oder globalen Gültigkeitsbereich), sodass sie die eigenen Eigenschaften des Objekts nicht sieht:
Verwenden Sie die reguläre Methoden-Kurzschreibweise (oder einen function-Ausdruck) für Objektmethoden. Siehe Objektmethoden, „this" für das vollständige Bild.
Prototyp-Methoden und Konstruktoren
Da Arrow-Funktionen nicht konstruierbar sind und kein eigenes this haben, können sie keine Prototyp-Methoden definieren oder als Konstruktorfunktionen dienen. Methoden, die einem Prototyp hinzugefügt werden, müssen reguläre Funktionen sein, damit jede Instanz this auf sich selbst auflöst.
DOM-Ereignishandler (im Browser)
Wenn Sie einen Handler mit addEventListener hinzufügen, ruft der Browser ihn mit this auf, das auf das Element gesetzt ist, das das Ereignis empfangen hat. Eine Arrow-Funktion ignoriert das und behält das äußere this, daher sollten Sie eine reguläre Funktion verwenden, wenn this das Element sein soll (Sie können in beiden Fällen immer event.currentTarget verwenden).
Fortgeschrittene Techniken
Object-Literale zurückgeben
Um ein Object-Literal aus einer Arrow-Funktion zurückzugeben, schließen Sie das object in Klammern ein:
IIFE mit Arrow-Funktionen
Arrow-Funktionen können für sofort aufgerufene Funktionsausdrücke (IIFE) verwendet werden:
Zusammenfassung
Arrow-Funktionen lassen sich am besten durch das verstehen, was ihnen fehlt. Sie haben:
- Kein eigenes
this— es wird aus dem umgebenden Gültigkeitsbereich übernommen (lexikalischesthis), und.call/.apply/.bindkönnen es nicht ändern. Ideal für Callbacks, falsch für Objektmethoden. - Kein eigenes
arguments— verwenden Sie Rest-Parameter (...args), wenn Sie diese benötigen. - Kein
super— daher können sie keine Klassenmethoden sein, die eine übergeordnete Klasse aufrufen. - Kein
[[Construct]]und keinprototype— daher können sie nicht mitnewoder als Prototyp-Methoden verwendet werden.
Verwenden Sie Arrow-Funktionen für kurze Callbacks und jede Funktion, die ihr äußeres this beibehalten soll. Verwenden Sie reguläre Funktionen für Objektmethoden, Prototyp-Methoden, Konstruktoren und DOM-Handler, die ein dynamisches this benötigen.
Verwandte Kapitel
- Arrow-Funktionen, die Grundlagen
- Objektmethoden, „this"
- Funktionsbindung
- Konstruktor, Operator „new"
- Rest-Parameter und Spread-Syntax