function sum() {
let args = [].slice.call(arguments);
// ...
}
// vs
const sum = (...args) => {
// ...
};
Ähnliche Fragen zu Pfeilfunktionen sind immer häufiger aufgetaucht, da ES2015 immer beliebter wird. Ich hatte nicht das Gefühl, dass es eine gute kanonische Frage/Antwort für dieses Problem gibt, also habe ich diese erstellt. Wenn Sie der Meinung sind, dass es bereits eine gute gibt, lassen Sie es mich bitte wissen und ich werde diese als Duplikat schließen oder löschen. Fühlen Sie sich frei, die Beispiele zu verbessern oder neue hinzuzufügen.
– Felix Klinge
18. Dezember 2015 um 17:59 Uhr
Was ist mit JavaScript ecma6, um die normale Funktion in eine Pfeilfunktion zu ändern? Natürlich kann eine normale Frage niemals so gut und generisch sein wie eine, die speziell als kanonische Frage geschrieben wurde.
– Bergi
18. Dezember 2015 um 23:53 Uhr
Sehen Sie sich dieses Plnkr-Beispiel an Die Variable this ist sehr unterschiedlich timesCalled erhöht sich bei jedem Aufruf nur um 1. Was meine persönliche Frage beantwortet: .click( () => { } ) und .click(function() { })beide erstellen die gleiche Anzahl von Funktionen, wenn sie in einer Schleife verwendet werden, wie Sie anhand der Guid-Anzahl im Plnkr sehen können.
– jmbbild
12. September 2016 um 14:01 Uhr
Verwandter Beitrag – Wann sollte ich Arrow-Funktionen in ECMAScript 6 verwenden?
– RBT
26. Juni 2019 um 8:36 Uhr
Siehe auch: Wie funktioniert das Schlüsselwort „this“?.
– Sebastian Simon
21. Juni 2021 um 6:43 Uhr
Felix Klinge
tl;dr:Nein! Pfeilfunktionen und Funktionsdeklarationen/-ausdrücke sind nicht gleichwertig und können nicht blind ersetzt werden.
Wenn die Funktion, die Sie ersetzen möchten, funktioniert nicht verwenden this, arguments und wird nicht mit angerufen newdann ja.
Wie so oft: es hängt davon ab, ob. Pfeilfunktionen haben ein anderes Verhalten als Funktionsdeklarationen / -ausdrücke, also schauen wir uns zuerst die Unterschiede an:
1. Lexikalisch this und arguments
Pfeilfunktionen haben keine eigenen this oder arguments Bindung. Stattdessen werden diese Bezeichner im lexikalischen Gültigkeitsbereich wie jede andere Variable aufgelöst. Das bedeutet, dass innerhalb einer Pfeilfunktion this und arguments beziehen sich auf die Werte von this und arguments In der Umgebung ist die Pfeilfunktion definiert in (dh “außerhalb” der Pfeilfunktion):
// Example using a function expression
function createObject() {
console.log('Inside `createObject`:', this.foo);
return {
foo: 42,
bar: function() {
console.log('Inside `bar`:', this.foo);
},
};
}
createObject.call({foo: 21}).bar(); // override `this` inside createObject
// Example using a arrow function
function createObject() {
console.log('Inside `createObject`:', this.foo);
return {
foo: 42,
bar: () => console.log('Inside `bar`:', this.foo),
};
}
createObject.call({foo: 21}).bar(); // override `this` inside createObject
Im Fall des Funktionsausdrucks this bezieht sich auf das Objekt, das innerhalb der erstellt wurde createObject. Im Fall der Pfeilfunktion gilt: this bezieht sich auf this von createObject selbst.
Dies macht Pfeilfunktionen nützlich, wenn Sie auf die zugreifen müssen this der aktuellen Umgebung:
// currently common pattern
var that = this;
getData(function(data) {
that.data = data;
});
// better alternative with arrow functions
getData(data => {
this.data = data;
});
Notiz dass dies auch bedeutet, dass ist nicht möglich, eine Pfeilfunktion einzustellen this mit .bind oder .call.
Wenn Sie nicht sehr vertraut sind thiserwägen Sie zu lesen
2. Pfeilfunktionen können nicht mit aufgerufen werden new
ES2015 unterscheidet zwischen Funktionen, die sind Anrufin der Lage und Funktionen, die sind bauenfähig. Wenn eine Funktion konstruierbar ist, kann sie mit aufgerufen werden newdh new User(). Wenn eine Funktion aufrufbar ist, kann sie auch ohne aufgerufen werden new (dh normaler Funktionsaufruf).
Durch Funktionsdeklarationen / -ausdrücke erstellte Funktionen sind sowohl konstruierbar als auch aufrufbar.
Pfeilfunktionen (und Methoden) sind nur aufrufbar. class Konstruktoren sind nur konstruierbar.
Wenn Sie versuchen, eine nicht aufrufbare Funktion aufzurufen oder eine nicht konstruierbare Funktion zu konstruieren, erhalten Sie einen Laufzeitfehler.
Wenn wir dies wissen, können wir Folgendes sagen.
Austauschbar:
Funktionen, die nicht verwendet werden this oder arguments.
Funktionen, die mit verwendet werden .bind(this)
Nicht austauschbar:
Konstruktorfunktionen
Funktion/Methoden, die einem Prototyp hinzugefügt wurden (weil sie normalerweise this)
Variadische Funktionen (wenn sie verwenden arguments (siehe unten))
Generatorfunktionen, die die function* Notation
Schauen wir uns das anhand Ihrer Beispiele genauer an:
Konstruktorfunktion
Dies funktioniert nicht, da Pfeilfunktionen nicht mit aufgerufen werden können new. Verwenden Sie weiterhin eine Funktionsdeklaration / einen Ausdruck oder verwenden Sie sie class.
Prototypische Methoden
Höchstwahrscheinlich nicht, da normalerweise Prototypmethoden verwendet werden this um auf die Instanz zuzugreifen. Wenn sie nicht verwenden this, dann kannst du es ersetzen. Wenn Sie jedoch in erster Linie Wert auf eine präzise Syntax legen, verwenden Sie class mit seiner prägnanten Methodensyntax:
class User {
constructor(name) {
this.name = name;
}
getName() {
return this.name;
}
}
Objektmethoden
Ähnlich für Methoden in einem Objektliteral. Wenn die Methode das Objekt selbst über referenzieren möchte thisverwenden Sie weiterhin Funktionsausdrücke oder verwenden Sie die neue Methodensyntax:
const obj = {
getName() {
// ...
},
};
Rückrufe
Es hängt davon ab, ob. Sie sollten es auf jeden Fall ersetzen, wenn Sie das Äußere aliasieren this oder verwenden .bind(this):
// old
setTimeout(function() {
// ...
}.bind(this), 500);
// new
setTimeout(() => {
// ...
}, 500);
Aber: Wenn der Code, der den Callback aufruft, explizit setzt this auf einen bestimmten Wert, wie es oft bei Event-Handlern der Fall ist, insbesondere bei jQuery, und die Callback-Verwendungen this (oder arguments), Sie kann nicht Verwenden Sie eine Pfeilfunktion!
Variadische Funktionen
Da Pfeilfunktionen keine eigenen haben arguments, Sie können sie nicht einfach durch eine Pfeilfunktion ersetzen. ES2015 führt jedoch eine Alternative zur Verwendung ein arguments: der Ruheparameter.
// old
function sum() {
let args = [].slice.call(arguments);
// ...
}
// new
const sum = (...args) => {
// ...
};
Verwandte Frage:
Wann sollte ich Pfeilfunktionen in ECMAScript 6 verwenden?
Haben ES6-Pfeilfunktionen ihre eigenen Argumente oder nicht?
Was sind die Unterschiede (falls vorhanden) zwischen ES6-Pfeilfunktionen und Funktionen, die mit Function.prototype.bind gebunden sind?
Wie verwendet man Pfeilfunktionen (öffentliche Klassenfelder) als Klassenmethoden?
Erwähnenswert ist vielleicht, dass die lexikalische this wirkt sich auch aus super und dass sie keine haben .prototype.
– loganfsmyth
18. Dezember 2015 um 22:13 Uhr
Es wäre auch gut zu erwähnen, dass sie syntaktisch nicht austauschbar sind — eine Pfeilfunktion (AssignmentExpression) kann nicht einfach überall ein Funktionsausdruck (PrimaryExpression).
– JMM
1. April 2016 um 22:49 Uhr
@JMM: “Es bringt Leute ziemlich häufig zum Stolpern” kannst du ein konkretes beispiel nennen? Wenn Sie die Spezifikation überfliegen, scheint es, dass die Stellen, an denen Sie ein FE, aber kein AF platzieren können, sowieso zu Laufzeitfehlern führen würden …
– Felix Klinge
1. April 2016 um 22:54 Uhr
Sicher, ich meine Dinge wie den Versuch, sofort eine Pfeilfunktion wie einen Funktionsausdruck (() => {}()) oder so etwas tun x || () => {}. Das meine ich: Laufzeit-(Parse-)Fehler. (Und obwohl das der Fall ist, denken die Leute ziemlich häufig, dass der Fehler ein Fehler ist.) Versuchen Sie nur, logische Fehler abzudecken, die unbemerkt bleiben würden, weil sie nicht unbedingt Fehler machen, wenn sie analysiert oder ausgeführt werden? new‘ing one ist ein Laufzeitfehler, oder?
– JMM
1. April 2016 um 23:27 Uhr
Hier sind einige Links davon, die in freier Wildbahn auftauchen: substack/node-browserify#1499, babel/babel-eslint#245 (Dies ist ein asynchroner Pfeil, aber ich denke, es ist das gleiche grundlegende Problem) und eine Reihe von Problemen auf Babel, die jetzt schwer zu finden sind, aber hier ist eines T2847.
– JMM
1. April 2016 um 23:27 Uhr
Aschutosch
Pfeilfunktionen => bisher beste ES6-Funktion. Sie sind eine enorm leistungsstarke Ergänzung zu ES6, die ich ständig verwende.
Warten Sie, Sie können die Pfeilfunktion nicht überall in Ihrem Code verwenden, es wird nicht in allen Fällen funktionieren this wo Pfeilfunktionen nicht verwendbar sind. Ohne Zweifel ist die Pfeilfunktion eine großartige Ergänzung, die Code-Einfachheit bringt.
Aber Sie können keine Pfeilfunktion verwenden, wenn ein dynamischer Kontext erforderlich ist: Methoden definieren, Objekte mit Konstruktoren erstellen, das Ziel davon erhalten, wenn Sie Ereignisse behandeln.
Pfeilfunktionen sollten NICHT verwendet werden, weil:
Sie haben nicht this
Es verwendet „lexical scoping“, um herauszufinden, was der Wert von „this” sollte sein. Im einfachen lexikalischen Scoping verwendet es „this” aus dem Inneren des Körpers der Funktion.
Sie haben nicht arguments
Pfeilfunktionen haben kein arguments Objekt. Die gleiche Funktionalität kann jedoch mit Restparametern erreicht werden.
let sum = (...args) => args.reduce((x, y) => x + y, 0) sum(3, 3, 1) // output - 7
`
Sie können nicht mit verwendet werdennew
Pfeilfunktionen können keine Konstruktoren sein, da sie keine Prototypeigenschaft haben.
Wann Sie die Pfeilfunktion verwenden und wann nicht:
Verwenden Sie nicht, um eine Funktion als Eigenschaft im Objektliteral hinzuzufügen, da wir darauf nicht zugreifen können.
Funktionsausdrücke eignen sich am besten für Objektmethoden. Pfeilfunktionen eignen sich am besten für Rückrufe oder Methoden wie map, reduceoder forEach.
Verwenden Sie Funktionsdeklarationen für Funktionen, die Sie namentlich aufrufen würden (weil sie gehisst sind).
Verwenden Sie Pfeilfunktionen für Rückrufe (weil sie dazu neigen, knapper zu sein).
die 2. Sie haben keine Argumente, tut mir leid, ist nicht wahr, man kann Argumente haben, ohne den Operator … zu verwenden, vielleicht möchten Sie sagen, dass Sie kein Array als Argument haben
Sie sind nicht immer gleichwertig. Hier ist ein Fall, in dem Sie nicht einfach Pfeilfunktionen anstelle von regulären Funktionen verwenden können.
Pfeilfunktionen können NICHT als Konstruktoren verwendet werden
TLDR:
Dies liegt daran, wie Pfeilfunktionen die verwenden Das Stichwort. JS gibt einfach einen Fehler aus, wenn es sieht, dass eine Pfeilfunktion als “Konstruktor” aufgerufen wird. Verwenden Sie reguläre Funktionen, um den Fehler zu beheben.
Längere Erklärung:
Dies liegt daran, dass Objekt-“Konstruktoren” auf die angewiesen sind Das Schlüsselwort geändert werden kann.
Im Allgemeinen die Das Das Schlüsselwort verweist immer auf das globale Objekt. (Im Browser ist es die Fenster Objekt).
ABER, wenn Sie so etwas tun:
function personCreator(name) {
this.name = name;
}
const person1 = new personCreator('John');
Die Neu Schlüsselwort macht etwas von seiner Magie und macht die Das Schlüsselwort, das innerhalb von ist PersonErsteller zunächst ein leeres Objekt sein, anstatt auf das globale Objekt zu verweisen. Danach rief eine neue Eigenschaft an Name wird in diesem leeren erstellt Das Objekt, und sein Wert wird ‘John’ sein. Am Ende, die Das Objekt wird zurückgegeben.
Wie wir sehen, die Neu Schlüsselwort hat den Wert von geändert Das vom Verweis auf die global Objekt ist jetzt ein leeres Objekt {}.
Pfeilfunktionen lassen ihre nicht zu Das zu änderndes Objekt. Ihr Das Objekt ist immer dasjenige aus dem Gültigkeitsbereich, in dem sie statisch erstellt wurden. Das nennt man Statischer lexikalischer Umfang. Deshalb können Sie keine Operationen wie durchführen binden, anwendenoder Anruf mit Pfeilfunktionen. Einfach ihre Das ist auf den Wert von gesperrt Das des Geltungsbereichs, in dem sie erstellt wurden. Dies ist beabsichtigt.
Und aus diesem Grund: D können Pfeilfunktionen nicht als “Konstruktoren” verwendet werden.
Randnotiz:
Ein lexikalischer Gültigkeitsbereich ist nur der Bereich, in dem eine Funktion erstellt wird. Zum Beispiel:
Der lexikalische Geltungsbereich von Bar ist alles, was drinnen ist foo. Also, die Das Wert von Bar ist derjenige, der foo hat, das ist derjenige von PersonErsteller.
9868600cookie-checkSind „Pfeilfunktionen“ und „Funktionen“ gleichwertig / austauschbar?yes
Ähnliche Fragen zu Pfeilfunktionen sind immer häufiger aufgetaucht, da ES2015 immer beliebter wird. Ich hatte nicht das Gefühl, dass es eine gute kanonische Frage/Antwort für dieses Problem gibt, also habe ich diese erstellt. Wenn Sie der Meinung sind, dass es bereits eine gute gibt, lassen Sie es mich bitte wissen und ich werde diese als Duplikat schließen oder löschen. Fühlen Sie sich frei, die Beispiele zu verbessern oder neue hinzuzufügen.
– Felix Klinge
18. Dezember 2015 um 17:59 Uhr
Was ist mit JavaScript ecma6, um die normale Funktion in eine Pfeilfunktion zu ändern? Natürlich kann eine normale Frage niemals so gut und generisch sein wie eine, die speziell als kanonische Frage geschrieben wurde.
– Bergi
18. Dezember 2015 um 23:53 Uhr
Sehen Sie sich dieses Plnkr-Beispiel an Die Variable
this
ist sehr unterschiedlichtimesCalled
erhöht sich bei jedem Aufruf nur um 1. Was meine persönliche Frage beantwortet:.click( () => { } )
und.click(function() { })
beide erstellen die gleiche Anzahl von Funktionen, wenn sie in einer Schleife verwendet werden, wie Sie anhand der Guid-Anzahl im Plnkr sehen können.– jmbbild
12. September 2016 um 14:01 Uhr
Verwandter Beitrag – Wann sollte ich Arrow-Funktionen in ECMAScript 6 verwenden?
– RBT
26. Juni 2019 um 8:36 Uhr
Siehe auch: Wie funktioniert das Schlüsselwort „this“?.
– Sebastian Simon
21. Juni 2021 um 6:43 Uhr