aboutsummaryrefslogtreecommitdiff
path: root/files/de/web/javascript/reference/functions/pfeilfunktionen/index.html
diff options
context:
space:
mode:
Diffstat (limited to 'files/de/web/javascript/reference/functions/pfeilfunktionen/index.html')
-rw-r--r--files/de/web/javascript/reference/functions/pfeilfunktionen/index.html360
1 files changed, 360 insertions, 0 deletions
diff --git a/files/de/web/javascript/reference/functions/pfeilfunktionen/index.html b/files/de/web/javascript/reference/functions/pfeilfunktionen/index.html
new file mode 100644
index 0000000000..a29b5ea3cf
--- /dev/null
+++ b/files/de/web/javascript/reference/functions/pfeilfunktionen/index.html
@@ -0,0 +1,360 @@
+---
+title: Pfeilfunktionen
+slug: Web/JavaScript/Reference/Functions/Pfeilfunktionen
+tags:
+ - ECMAScript 2015
+ - Functions
+ - Intermediate
+ - JavaScript
+ - Reference
+translation_of: Web/JavaScript/Reference/Functions/Arrow_functions
+---
+<div>{{jsSidebar("Functions")}}</div>
+
+<p>Der <strong>Ausdruck einer Pfeilfunktion</strong> hat eine kürzere Syntax als ein <a href="/de/docs/Web/JavaScript/Reference/Operators/function">Funktionsausdruck</a> und hat kein eigenes <code><a href="/de/docs/Web/JavaScript/Reference/Operators/this">this</a></code>, <a href="/de/docs/Web/JavaScript/Reference/Functions/arguments">arguments</a>, <a href="/de/docs/Web/JavaScript/Reference/Operators/super">super</a>, oder <a href="/de/docs/Web/JavaScript/Reference/Operators/new.target">new.target</a>. Solche Funktionsausdrücke sind am besten für Funktionen, die nicht als Methode genutzt werden, geeignet und können nicht als Konstruktoren verwendet werden.</p>
+
+<div>{{EmbedInteractiveExample("pages/js/functions-arrow.html")}}</div>
+
+<h2 id="Syntax">Syntax</h2>
+
+<h3 id="Basis_Syntax">Basis Syntax</h3>
+
+<pre class="syntaxbox">(param1, param2, …, paramN) =&gt; { statements }
+(param1, param2, …, paramN) =&gt; expression
+// gleich zu: =&gt; { return expression; }
+
+// Klammern sind optional, wenn nur ein Parametername vorhanden ist:
+(singleParam) =&gt; { statements }
+singleParam =&gt; { statements }
+
+// Die Parameterliste für eine parameterlose Funktion muss mit einem Klammernpaar geschrieben werden
+() =&gt; { statements }
+</pre>
+
+<h3 id="Fortgeschrittene_Syntax">Fortgeschrittene Syntax</h3>
+
+<pre class="syntaxbox">// Der Body kann eingeklammert werden, um ein Objektliteral Ausdruck zurück zu geben:
+params =&gt; ({foo: bar})
+
+// <a href="/de/docs/Web/JavaScript/Reference/Functions/rest_parameters">Rest Parameter</a> und <a href="/de/docs/Web/JavaScript/Reference/Functions/Default_parameters">Default Parameter</a> werden unterstützt
+(param1, param2, ...rest) =&gt; { statements }
+(param1 = defaultValue1, param2, …, paramN = defaultValueN) =&gt; {
+statements }
+
+// <a href="/de/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">Destrukturierung</a> in der Parameterliste ist ebenfalls unterstützt
+var f = ([a, b] = [1, 2], {x: c} = {x: a + b}) =&gt; a + b + c;
+f(); // 6
+</pre>
+
+<h2 id="Beschreibung">Beschreibung</h2>
+
+<p>Siehe auch <a href="https://hacks.mozilla.org/2015/06/es6-in-depth-arrow-functions/">"ES6 In Depth: Arrow functions" on hacks.mozilla.org</a>.</p>
+
+<p>Zwei Faktoren haben die Einführung von Pfeilfunktionen beeinflusst: kürzere Funktionen und dass <code>this</code> nicht gebunden ist.</p>
+
+<h3 id="Kürzere_Funktionen">Kürzere Funktionen</h3>
+
+<pre class="brush: js">var elements = [
+ "Hydrogen",
+ "Helium",
+ "Lithium",
+ "Beryllium"
+];
+
+elements.map(function(element) {
+ return element.length
+}); // [8, 6, 7, 9]
+
+elements.map(element =&gt; {
+ return element.length
+}); // [8, 6, 7, 9]
+
+elements.map(({length}) =&gt; length); // [8, 6, 7, 9]</pre>
+
+<h3 id="Keine_Bindung_von_this">Keine Bindung von <code>this</code></h3>
+
+<p>Vor (der Einführung von) Pfeilfunktionen definierte jede Funktion ihren eigenen <code><a href="/de/docs/Web/JavaScript/Reference/Operators/this">this</a></code>-Wert (d.h. ein neues Objekt im Falle eines Konstruktors; in <a href="/de/docs/Web/JavaScript/Reference/Strict_mode">strict mode</a> Funktionsaufrufen nicht definiert; bzw. das kontextuelle Objekt, wenn die Funktion als eine "Objekt-Methode" aufgerufen wurde, usw.). Dies stellte sich innerhalb eines objektorientierten Programmierstils als lästig heraus.</p>
+
+<pre class="brush: js">function Person() {
+ // Der Person() Konstruktor definiert `this` als Instanz von sich selbst.
+ this.age = 0;
+
+ setInterval(function growUp() {
+ // Im nicht Strict Modus, definiert die growUp() Funktion `this`
+ // als das globale Objekt (weil das der Ort ist, an dem growUp() ausgeführt wird),
+ // das sich von dem `this`, welches vom Person() Konstruktor definiert wurde unterscheidet.
+ this.age++;
+ }, 1000);
+}
+
+var p = new Person();</pre>
+
+<p>In ECMAScript 3/5 konnte dies durch Zuweisung des Wertes von <code>this</code> an eine Variable, welche umschlossen werden konnte, behoben werden.</p>
+
+<pre class="brush: js">function Person() {
+ var that = this;
+ that.age = 0;
+
+ setInterval(function growUp() {
+ // Der Rückruf bezieht sich auf jene `that`-Variable,
+ // deren Wert das zu erwartende Objekt ist.
+ that.age++;
+ }, 1000);
+}</pre>
+
+<p>Alternativ könnte eine <a href="/de/docs/Web/JavaScript/Reference/Global_Objects/Function/bind">gebundene Funktion</a> erstellt werden, sodass der passende <code>this</code>-Wert an die <code>growUp()</code>-Funktion übergeben würde.</p>
+
+<p>Eine Pfeilfunktion erstellt keinen eigenen <code>this</code> Kontext, wodurch <code>this</code> die ursprüngliche Bedeutung des umschließenden Kontextes trägt. Somit funktioniert der folgende Code wie erwartet.</p>
+
+<pre class="brush: js">function Person(){
+ this.age = 0;
+
+ setInterval(() =&gt; {
+ this.age++; // |this| bezieht sich entsprechend auf das Person-Objekt
+ }, 1000);
+}
+
+var p = new Person();</pre>
+
+<h4 id="Zusammenhang_mit_dem_Strict_Mode">Zusammenhang mit dem Strict Mode</h4>
+
+<p>Vorausgesetzt, dass <code>this</code> aus dem umschließenden lexikalischen Kontext kommt, werden <a href="/de/docs/Web/JavaScript/Reference/Strict_mode">Strict Mode</a> Regeln bezüglich <code>this</code> einfach ignoriert.</p>
+
+<pre class="brush: js">var f = () =&gt; {'use strict'; return this};
+f() === window; // oder das globale Objekt</pre>
+
+<p>Die restlichen strict mode Regeln verhalten sich normal.</p>
+
+<h4 id="Aufruf_durch_call_oder_apply">Aufruf durch call oder apply</h4>
+
+<p>Da <code>this</code><em> </em>in Pfeilfunktionen nicht gebunden ist, können <code>call()</code><em> </em>oder <code>apply()</code> Methoden nur Argumente übergeben; <code>this</code> wird ignoriert:</p>
+
+<pre class="brush: js">var adder = {
+ base : 1,
+
+ add : function(a) {
+ var f = v =&gt; v + this.base;
+ return f(a);
+ },
+
+ addThruCall: function(a) {
+ var f = v =&gt; v + this.base;
+ var b = {
+ base : 2
+ };
+
+ return f.call(b, a);
+ }
+};
+
+console.log(adder.add(1)); // Dies würde 2 ausgeben
+console.log(adder.addThruCall(1)); // Dies würde nach wie vor 2 ausgeben</pre>
+
+<h3 id="Keine_Bindung_von_Argumenten">Keine Bindung von Argumenten</h3>
+
+<p>Pfeilfunktionen haben kein eigenes <a href="/de/docs/Web/JavaScript/Reference/Functions/arguments"><code>arguments</code> Objekt</a>. Somit ist <code>arguments</code> einfach eine Referenz auf den Namen innerhalb des umschließenden Geltungsbereichs (scope).</p>
+
+<pre class="brush: js">var arguments = [1, 2, 3];
+var arr = () =&gt; arguments[0];
+
+arr(); // 1
+
+function foo(n) {
+ var f = () =&gt; arguments[0] + n; // implizite Argumenten-Bindung von <em>foo</em>
+ return f();
+}
+
+foo(1); // 2</pre>
+
+<p>In den meisten Fällen sind <a href="/de/docs/Web/JavaScript/Reference/Functions/rest_parameters">Rest Parameters</a> eine gute Alternative zum Einsatz des <code>arguments</code> Objektes:</p>
+
+<pre class="brush: js">function foo(n) {
+ var f = (...args) =&gt; args[0] + n;
+ return f(10);
+}
+
+foo(1); // 11</pre>
+
+<h3 id="Pfeilfunktionen_als_Methoden">Pfeilfunktionen als Methoden</h3>
+
+<p>Wie angegeben, sind Ausdrücke von Pfeilfunktionen am besten geeignet für nicht-methodische Funktionen. Man sehe, was geschieht, wenn versucht wird, sie als Methoden zu verwenden.</p>
+
+<pre class="brush: js">'use strict';
+
+var obj = {
+ i: 10,
+ b: () =&gt; console.log(this.i, this),
+ c: function() {
+ console.log( this.i, this)
+ }
+}
+obj.b(); // gibt undefined, Window {...} aus (oder das globale Objekt)
+obj.c(); // gibt 10, Object {...} aus</pre>
+
+<p>Pfeilfunktionen definieren (binden sozusagen) kein eigenes <code>this</code>. Ein anderes Beispiel, das {{jsxref("Object.defineProperty()")}} betrifft:</p>
+
+<pre class="brush: js">'use strict';
+
+var obj = {
+ a: 10
+};
+
+Object.defineProperty(obj, "b", {
+ get: () =&gt; {
+ console.log(this.a, typeof this.a, this);
+ return this.a+10; // stellt das globale Objekt 'Window' dar, 'this.a' gibt daher 'undefined' zurück
+ }
+});
+</pre>
+
+<h3 id="Verwendung_des_new_Operators">Verwendung des <code>new</code> Operators</h3>
+
+<p>Pfeilfunktionen können nicht als Konstruktoren verwendet werden. Sie führen zu einem Fehler, wenn auf ihnen ein <code>new</code> angewendet wird.</p>
+
+<pre class="brush: js">var Foo = () =&gt; {};
+var foo = new Foo(); // TypeError: Foo is not a constructor
+</pre>
+
+<h3 id="Einsatz_der_prototype_Eigenschaft">Einsatz der <code>prototype</code> Eigenschaft</h3>
+
+<p>Pfeilfunktionen haben keine <code>prototype</code> Eigenschaft.</p>
+
+<pre class="brush: js">var Foo = () =&gt; {};
+console.log(Foo.prototype); // undefined
+</pre>
+
+<h3 id="Verwendung_des_Schlüsselwortes_yield">Verwendung des Schlüsselwortes <code>yield</code></h3>
+
+<p>Das <code><a href="/de/docs/Web/JavaScript/Reference/Operators/yield">yield</a></code>-Schlüsselwort sollte im Körper einer Pfeilfunktion nicht verwendet werden (außer wenn dies innerhalb von darin weiter verschachtelten Funktionen erlaubt ist). Als Folge können Pfeilfunktionen nicht als Generatoren verwendet werden.</p>
+
+<h2 id="Funktionskörper">Funktionskörper</h2>
+
+<p>Pfeilfunktionen können entweder einen "knappen" oder einen gewöhnlichen "Blockkörper" haben.</p>
+
+<p>In einem knappen Körper ist lediglich ein Ausdruck nötig und eine implizite Rückgabe wird angehängt. In einem Blockkörper muss eine explizite Rückgabe-Anweisung verwendet werden.</p>
+
+<pre class="brush: js">var func = x =&gt; x * x;
+// knappe Syntax, implizierte Rückgabe
+
+var func = (x, y) =&gt; { return x + y; };
+// mit Blockkörper, explizite Rückgabe wird benötigt
+</pre>
+
+<h2 id="Rückgabe_von_Objekt-Literalen">Rückgabe von Objekt-Literalen</h2>
+
+<p>Man bedenke, dass die Rückgabe von Objekt-Literalen unter Verwendung der knappen Syntax <code>params =&gt; {object:literal}</code> nicht so ausgeführt wird, wie man es erwarten würde:</p>
+
+<pre class="brush: js">var func = () =&gt; { foo: 1 };
+// Der Aufruf von func() gibt undefined zurück!
+
+var func = () =&gt; { foo: function() {} };
+// SyntaxError: function-Anweisung erfordert einen Namen</pre>
+
+<p>Der Grund dafür ist, dass der Code in geschweiften Klammern ({}) als eine Sequenz von Anweisungen übersetzt wird (d.h. foo wird als Bezeichner behandelt und nicht als Schlüssel eines Objekt-Literals).</p>
+
+<p>Man bedenke, das Objekt-Literal in Klammern zu setzen:</p>
+
+<pre class="brush: js">var func = () =&gt; ({ foo: 1 });</pre>
+
+<h2 id="Zeilenumbruch">Zeilenumbruch</h2>
+
+<p>Pfeilfunktionen können keinen Zeilenumbruch zwischen Parametern und dem Pfeil haben.</p>
+
+<pre class="brush: js">var func = ()
+ =&gt; 1;
+// SyntaxError: Ausdruck erwartet, '=&gt;' erhalten</pre>
+
+<h2 id="Übersetzungsreihenfolge">Übersetzungsreihenfolge</h2>
+
+<p>Der Pfeil innerhalb einer Pfeilfunktion ist kein Operator. Allerdings haben Pfeilfunktionen im Vergleich zu gewöhnlichen Funktionen besondere Übersetzungsregeln, welche mit der Priorität von Operatoren (<a href="/de/docs/Web/JavaScript/Reference/Operators/Operator_Precedence">operator precedence</a>) anders interagieren.</p>
+
+<pre class="brush: js">let callback;
+
+callback = callback || function() {}; // ok
+
+callback = callback || () =&gt; {};
+// SyntaxError: invalid arrow-function arguments
+
+callback = callback || (() =&gt; {}); // ok
+</pre>
+
+<h2 id="Weitere_Beispiele">Weitere Beispiele</h2>
+
+<pre class="brush: js">// Eine leere Pfeilfunktion gibt undefined zurück
+let empty = () =&gt; {};
+
+(() =&gt; "foobar")()
+// Gibt "foobar" zurück
+// (Das ist eine Immediately Invoked Function Expression
+// siehe IIFE im Glossar
+
+var simple = a =&gt; a &gt; 15 ? 15 : a;
+simple(16); // 15
+simple(10); // 10
+
+let max = (a, b) =&gt; a &gt; b ? a : b;
+
+// Einfaches filtering, mapping, ... von Arrays
+
+var arr = [5, 6, 13, 0, 1, 18, 23];
+
+var sum = arr.reduce((a, b) =&gt; a + b);
+// 66
+
+var even = arr.filter(v =&gt; v % 2 == 0);
+// [6, 0, 18]
+
+var double = arr.map(v =&gt; v * 2);
+// [10, 12, 26, 0, 2, 36, 46]
+
+// Weitere knappe Zusicherungsketten (promise chains)
+promise.then(a =&gt; {
+ // ...
+}).then(b =&gt; {
+ // ...
+});
+
+// Parameterlose Pfeilfunktionen, welche visuell einfacher zu verstehen sind
+setTimeout( _ =&gt; {
+ console.log("I happen sooner");
+ setTimeout( _ =&gt; {
+ // deeper code
+ console.log("I happen later");
+ }, 1);
+}, 1);</pre>
+
+<h2 id="Spezifikationen">Spezifikationen</h2>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th scope="col">Spezifikation</th>
+ <th scope="col">Status</th>
+ <th scope="col">Kommentar</th>
+ </tr>
+ <tr>
+ <td>{{SpecName('ES2015', '#sec-arrow-function-definitions', 'Arrow Function Definitions')}}</td>
+ <td>{{Spec2('ES2015')}}</td>
+ <td>Initiale Definition.</td>
+ </tr>
+ <tr>
+ <td>{{SpecName('ESDraft', '#sec-arrow-function-definitions', 'Arrow Function Definitions')}}</td>
+ <td>{{Spec2('ESDraft')}}</td>
+ <td> </td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Browserkompatibilität">Browserkompatibilität</h2>
+
+<div>
+
+
+<p>{{Compat("javascript.functions.arrow_functions")}}</p>
+</div>
+
+<h2 id="Siehe_auch">Siehe auch</h2>
+
+<ul>
+ <li><a href="https://hacks.mozilla.org/2015/06/es6-in-depth-arrow-functions/">"ES6 In Depth: Arrow functions" on hacks.mozilla.org</a></li>
+</ul>