[ Web Proxy ]
URL:
Viewing: https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Functions/Arrow_functions [Back]  [Original]

Pfeilfunktionen (Arrow Function Expressions) - JavaScript | MDN

Dieser Inhalt wurde automatisch aus dem Englischen bersetzt, und kann Fehler enthalten. Erfahre mehr ber dieses Experiment.

View in English Always switch to English

Pfeilfunktionen (Arrow Function Expressions)

Baseline
Weitgehend verfgbar

Diese Funktion ist gut etabliert und funktioniert auf vielen Gerten und in vielen Browserversionen. Sie ist seit September 2016 browserbergreifend verfgbar.

Ein Arrow Function Expression ist eine kompakte Alternative zu einem traditionellen Function Expression, mit einigen semantischen Unterschieden und bewussten Einschrnkungen in der Verwendung:

  • Arrow-Funktionen haben keine eigenen Bindings zu this, arguments oder super und sollten nicht als Methoden verwendet werden.
  • Arrow-Funktionen knnen nicht als Konstruktoren verwendet werden. Ein Aufruf mit new fhrt zu einem TypeError. Sie haben auch keinen Zugriff auf das Schlsselwort new.target.
  • Arrow-Funktionen knnen innerhalb ihres Krpers kein yield verwenden und knnen nicht als Generatorfunktionen erstellt werden.

In diesem Artikel

Probieren Sie es aus

const materials = ["Hydrogen", "Helium", "Lithium", "Beryllium"];

console.log(materials.map((material) => material.length));
// Expected output: Array [8, 6, 7, 9]

Syntax

js
() => expression

param => expression

(param) => expression

(param1, paramN) => expression

() => {
  statements
}

param => {
  statements
}

(param1, paramN) => {
  statements
}

Restparameter, Standardparameter und Destructuring innerhalb von Parametern werden untersttzt und erfordern immer Klammern:

js
(a, b, ...r) => expression
(a = 400, b = 20, c) => expression
([a, b] = [10, 20]) => expression
({ a, b } = { a: 10, b: 20 }) => expression

Arrow-Funktionen knnen async sein, indem sie mit dem Schlsselwort async versehen werden.

js
async param => expression
async (param1, param2, ...paramN) => {
  statements
}

Beschreibung

Lassen Sie uns eine traditionelle anonyme Funktion Schritt fr Schritt auf die einfachste Arrow-Funktion reduzieren. Jeder Schritt ist eine gltige Arrow-Funktion.

Hinweis: Traditionelle Function Expressions und Arrow-Funktionen unterscheiden sich nicht nur in ihrer Syntax. Wir werden die Unterschiede in ihrem Verhalten in den nchsten Abschnitten ausfhrlicher vorstellen.

js
// Traditional anonymous function
(function (a) {
  return a + 100;
});

// 1. Remove the word "function" and place arrow between the argument and opening body brace
(a) => {
  return a + 100;
};

// 2. Remove the body braces and word "return"  the return is implied.
(a) => a + 100;

// 3. Remove the parameter parentheses
a => a + 100;

Im obigen Beispiel knnen sowohl die Klammern um den Parameter als auch die geschweiften Klammern um den Funktionskrper weggelassen werden. Allerdings knnen sie nur in bestimmten Fllen weggelassen werden.

Die Klammern knnen nur weggelassen werden, wenn die Funktion einen einzigen einfachen Parameter hat. Wenn sie mehrere Parameter, keine Parameter oder Standard-, destrukturierte oder Restparameter hat, sind die Klammern um die Parameterliste erforderlich.

js
// Traditional anonymous function
(function (a, b) {
  return a + b + 100;
});

// Arrow function
(a, b) => a + b + 100;

const a = 4;
const b = 2;

// Traditional anonymous function (no parameters)
(function () {
  return a + b + 100;
});

// Arrow function (no parameters)
() => a + b + 100;

Die geschweiften Klammern knnen nur weggelassen werden, wenn die Funktion direkt einen Ausdruck zurckgibt. Wenn der Krper Anweisungen enthlt, sind die Klammern erforderlich. In diesem Fall mssen Rckgabewerte explizit mit dem Schlsselwort return angegeben werden. Arrow-Funktionen knnen nicht erraten, was oder wann Sie etwas zurckgeben mchten.

js
// Traditional anonymous function
(function (a, b) {
  const chuck = 42;
  return a + b + chuck;
});

// Arrow function
(a, b) => {
  const chuck = 42;
  return a + b + chuck;
};

Arrow-Funktionen sind nicht von Haus aus mit einem Namen verbunden. Wenn die Arrow-Funktion sich selbst aufrufen muss, verwenden Sie stattdessen ein benanntes Function Expression. Sie knnen die Arrow-Funktion auch einer Variablen zuweisen, sodass Sie sie ber diese Variable referenzieren knnen.

js
// Traditional Function
function bob(a) {
  return a + 100;
}

// Arrow Function
const bob2 = (a) => a + 100;

Funktionskrper

Arrow-Funktionen knnen entweder einen Ausdruckskrper oder den blichen Blockkrper haben.

In einem Ausdruckskrper wird nur ein einzelner Ausdruck angegeben, der zum impliziten Rckgabewert wird. Der Blockkrper ist analog zu traditionellen Funktionskrpern, bei denen Rckgabewerte explizit mit dem Schlsselwort return angegeben werden mssen. Arrow-Funktionen sind nicht verpflichtet, einen Wert zurckzugeben. Wenn die Ausfhrung des Blockkrpers bis zum Ende ohne einen return-Befehl erreicht, gibt die Funktion wie andere Funktionen undefined zurck.

js
// Expression body
const add = (a, b) => a + b; // Implicitly returns a + b

// Block body
const add2 = (a, b) => {
  console.log(a, b);
  return a + b; // Must explicitly return a value
};

// No return value
const add3 = (b) => {
  a += b;
  // No return statement, so returns undefined
};

Die Rckgabe von Objektliteralen unter Verwendung der Ausdruckskrpersyntax (params) => { object: literal } funktioniert nicht wie erwartet.

js
const func = () => { foo: 1 };
// Calling func() returns undefined!

const func2 = () => { foo: function () {} };
// SyntaxError: function statement requires a name

const func3 = () => { foo() {} };
// SyntaxError: Unexpected token '{'

Dies liegt daran, dass JavaScript die Arrow-Funktion nur dann als einen Ausdruckskrper ansieht, wenn das Token, das dem Pfeil folgt, keine linke geschweifte Klammer ist, sodass der Code innerhalb der geschweiften Klammern ({}) als eine Folge von Anweisungen geparst wird, wobei foo ein Label ist, kein Schlssel in einem Objektliteral.

Um dies zu beheben, umgeben Sie das Objektliteral mit Klammern:

js
const func = () => ({ foo: 1 });

Kann nicht als Methoden verwendet werden

Arrow Function Expressions sollten nur fr Nicht-Methodenfunktionen verwendet werden, da sie kein eigenes this haben. Sehen wir uns an, was passiert, wenn wir versuchen, sie als Methoden zu verwenden:

js
"use strict";

const obj = {
  i: 10,
  b: () => console.log(this.i, this),
  c() {
    console.log(this.i, this);
  },
};

obj.b(); // logs undefined, Window { /*  */ } (or the global object)
obj.c(); // logs 10, Object { /*  */ }

Ein weiteres Beispiel mit Object.defineProperty():

js
"use strict";

const obj = {
  a: 10,
};

Object.defineProperty(obj, "b", {
  get: () => {
    console.log(this.a, typeof this.a, this); // undefined 'undefined' Window { /*  */ } (or the global object)
    return this.a + 10; // represents global object 'Window', therefore 'this.a' returns 'undefined'
  },
});

Da der Krper einer Klasse einen this-Kontext hat, schlieen Arrow-Funktionen als Klassenfelder den this-Kontext der Klasse ein, und das this innerhalb des Krpers der Arrow-Funktion verweist korrekt auf die Instanz (oder die Klasse selbst fr statische Felder). Da es sich jedoch um ein Closure handelt, nicht um das eigene Binding der Funktion, wird sich der Wert von this nicht ndern, basierend auf dem Ausfhrungskontext.

js
class C {
  a = 1;
  autoBoundMethod = () => {
    console.log(this.a);
  };
}

const c = new C();
c.autoBoundMethod(); // 1
const { autoBoundMethod } = c;
autoBoundMethod(); // 1
// If it were a normal method, it should be undefined in this case

Arrow-Funktionen werden oft als "automatisch gebundene Methoden" bezeichnet, da das quivalent bei normalen Methoden wie folgt ist:

js
class C {
  a = 1;
  constructor() {
    this.method = this.method.bind(this);
  }
  method() {
    console.log(this.a);
  }
}

Hinweis: Klassenfelder werden auf der Instanz definiert, nicht auf dem Prototyp, sodass bei jeder Instanzerstellung eine neue Funktionsreferenz erstellt und ein neues Closure zugewiesen wird, was potenziell zu einem hheren Speicherverbrauch fhren kann als bei einer normalen ungebundenen Methode.

Aus hnlichen Grnden sind die Methoden call(), apply() und bind() nicht ntzlich, wenn sie auf Arrow-Funktionen angewendet werden, da Arrow-Funktionen this basierend auf dem Scope festlegen, in dem die Arrow-Funktion definiert ist, und sich der Wert von this nicht ndert, basierend darauf, wie die Funktion aufgerufen wird.

Kein Binding von Arguments

Arrow-Funktionen haben kein eigenes arguments-Objekt. Daher referenziert arguments in diesem Beispiel die Argumente des umschlieenden Scopes:

js
function foo(n) {
  const f = () => arguments[0] + n; // foo's implicit arguments binding. arguments[0] is n
  return f();
}

foo(3); // 3 + 3 = 6

In den meisten Fllen ist die Verwendung von Rest-Parametern eine gute Alternative zur Verwendung eines arguments-Objekts.

js
function foo(n) {
  const f = (...args) => args[0] + n;
  return f(10);
}

foo(1); // 11

Kann nicht als Konstruktoren verwendet werden

Arrow-Funktionen knnen nicht als Konstruktoren verwendet werden und erzeugen einen Fehler, wenn sie mit new aufgerufen werden. Sie haben auch keine prototype-Eigenschaft.

js
const Foo = () => {};
const foo = new Foo(); // TypeError: Foo is not a constructor
console.log("prototype" in Foo); // false

Kann nicht als Generatoren verwendet werden

Das Schlsselwort yield kann in einem Arrow-Funktionskrper nicht verwendet werden (auer wenn es innerhalb von Generatorfunktionen eingesetzt wird, die weiter in der Arrow-Funktion verschachtelt sind). Infolgedessen knnen Arrow-Funktionen nicht als Generatoren verwendet werden.

Zeilenumbruch vor dem Pfeil

Eine Arrow-Funktion kann keinen Zeilenumbruch zwischen ihren Parametern und ihrem Pfeil enthalten.

js
const func = (a, b, c)
  => 1;
// SyntaxError: Unexpected token '=>'

Fr Formatierungszwecke knnen Sie den Zeilenumbruch nach dem Pfeil setzen oder Klammern/geschweifte Klammern um den Funktionskrper verwenden, wie unten gezeigt. Sie knnen auch Zeilenumbrche zwischen den Parametern einfgen.

js
const func = (a, b, c) =>
  1;

const func2 = (a, b, c) => (
  1
);

const func3 = (a, b, c) => {
  return 1;
};

const func4 = (
  a,
  b,
  c,
) => 1;

Przedenz des Pfeils

Obwohl der Pfeil in einer Arrow-Funktion kein Operator ist, haben Arrow-Funktionen spezielle Parsing-Regeln, die anders mit der Operatorprzedenz interagieren als regulre Funktionen.

js
let callback;

callback = callback || () => {};
// SyntaxError: invalid arrow-function arguments

Da => eine niedrigere Przedenz als die meisten Operatoren hat, sind Klammern erforderlich, um zu vermeiden, dass callback || () als Argumentliste der Arrow-Funktion geparst wird.

js
callback = callback || (() => {});

Beispiele

Verwendung von Arrow-Funktionen

js
// An empty arrow function returns undefined
const empty = () => {};

(() => "foobar")();
// Returns "foobar"
// (this is an Immediately Invoked Function Expression)

const simple = (a) => (a > 15 ? 15 : a);
simple(16); // 15
simple(10); // 10

const max = (a, b) => (a > b ? a : b);

// Easy array filtering, mapping, etc.
const arr = [5, 6, 13, 0, 1, 18, 23];

const sum = arr.reduce((a, b) => a + b);
// 66

const even = arr.filter((v) => v % 2 === 0);
// [6, 0, 18]

const double = arr.map((v) => v * 2);
// [10, 12, 26, 0, 2, 36, 46]

// More concise promise chains
promise
  .then((a) => {
    // 
  })
  .then((b) => {
    // 
  });

// Arrow functions without parameters
setTimeout(() => {
  console.log("I happen sooner");
  setTimeout(() => {
    // deeper code
    console.log("I happen later");
  }, 1);
}, 1);

Verwendung von call, bind und apply

Die Methoden call(), apply() und bind() funktionieren mit traditionellen Funktionen wie erwartet, da wir den Scope fr jede dieser Methoden festlegen:

js
const obj = {
  num: 100,
};

// Setting "num" on globalThis to show how it is NOT used.
globalThis.num = 42;

// A traditional function to operate on "this"
function add(a, b, c) {
  return this.num + a + b + c;
}

console.log(add.call(obj, 1, 2, 3)); // 106
console.log(add.apply(obj, [1, 2, 3])); // 106
const boundAdd = add.bind(obj);
console.log(boundAdd(1, 2, 3)); // 106

Bei Arrow-Funktionen wird unsere add-Funktion im Wesentlichen im globalThis (globalen) Scope erstellt, wodurch this globalThis entspricht.

js
const obj = {
  num: 100,
};

// Setting "num" on globalThis to show how it gets picked up.
globalThis.num = 42;

// Arrow function
const add = (a, b, c) => this.num + a + b + c;

console.log(add.call(obj, 1, 2, 3)); // 48
console.log(add.apply(obj, [1, 2, 3])); // 48
const boundAdd = add.bind(obj);
console.log(boundAdd(1, 2, 3)); // 48

Vielleicht der grte Vorteil der Verwendung von Arrow-Funktionen ist ihre Verwendung mit Methoden wie setTimeout() und EventTarget.prototype.addEventListener(), die normalerweise eine Art von Closure, call(), apply() oder bind() erfordern, um sicherzustellen, dass die Funktion im richtigen Scope ausgefhrt wird.

Bei traditionellen Function Expressions funktioniert Code wie dieser nicht wie erwartet:

js
const obj = {
  count: 10,
  doSomethingLater() {
    setTimeout(function () {
      // the function executes on the window scope
      this.count++;
      console.log(this.count);
    }, 300);
  },
};

obj.doSomethingLater(); // logs "NaN", because the property "count" is not in the window scope.

Mit Arrow-Funktionen wird der this-Scope leichter erhalten:

js
const obj = {
  count: 10,
  doSomethingLater() {
    // The method syntax binds "this" to the "obj" context.
    setTimeout(() => {
      // Since the arrow function doesn't have its own binding and
      // setTimeout (as a function call) doesn't create a binding
      // itself, the "obj" context of the outer method is used.
      this.count++;
      console.log(this.count);
    }, 300);
  },
};

obj.doSomethingLater(); // logs 11

Spezifikationen

Spezifikation
ECMAScript 2027 LanguageSpecification
# sec-arrow-function-definitions

Browser-Kompatibilitt

Siehe auch


Web Proxy Viewer  |  New URL  |  Original Page