1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
|
---
title: Funktionen
slug: Web/JavaScript/Reference/Functions
tags:
- Constructor
- Function
- Functions
- JavaScript
- Parameter
- parameters
translation_of: Web/JavaScript/Reference/Functions
---
<div>{{jsSidebar("Functions")}}</div>
<p>Allgemein gesagt, ist eine Funktion ein "Unterprogramm", welches von Code außerhalb der Funktion (oder innerhalb der Funktion, im Fall von Rekursion) aufgerufen wird. Wie Programme selbst auch, ist eine Funktion eine Sequenz von ausgewählten Statements, die als Funktionskörper bezeichnet wird. Der Funktion können der Werte übergeben werden und die Funktion wird einen Wert zurückgeben.</p>
<p>In JavaScript sind Funktionen First-Class Objekte, weil sie Eigenschaften und Methoden genau wie jedes andere Objekt haben können. Was sie von anderen Objekten unterscheidet ist, dass sie aufgerufen werden können. Kurz gesagt sind es <code><a href="/de/docs/JavaScript/Reference/Global_Objects/Function">Function</a></code> Objekte.</p>
<p>Für mehr Beispiele und Erklärungen, siehe auch im <a href="/de/docs/Web/JavaScript/Guide/Functions">JavaScript Guide über Funktionen</a>.</p>
<h2 id="Beschreibung">Beschreibung</h2>
<p>Jede Funktion in JavaScript ist ein <code>Function</code> Objekt. Siehe {{jsxref("Function")}} für mehr Informationen zu Eigenschaften und Methoden von <code>Function</code> Objekten.</p>
<p>Um einen Wert abweichend vom Standard zurückzugeben, muss eine Funktion ein <code><a href="/de/docs/Web/JavaScript/Reference/Statements/return">return</a></code> Statement haben, welches den Rückgabewert spezifiziert. Eine Funktion ohne ein return Statement wird den Standardwert zurückgeben. Im Fall eines <a href="/de/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor">Konstruktor</a>aufrufes mit dem Schlüsselwort <code><a href="/de/docs/Web/JavaScript/Reference/Operators/new">new</a></code>, wird der als Standardwert der Wert vom <code>this</code> Parameter zurückgegeben. Für alle anderen Funktionen wird als Standardwert {{jsxref("undefined")}} zurückgegeben.</p>
<p>Die Parameter eines Funktionsaufrufes sind die Argumente der Funktion. Argumente werden als Werte der Funktion übergeben. Wenn die Funktion den Wert eines Argumentes ändert, wirkt sich die Änderung nicht global oder in der aufrufenden Funktion aus. Jedoch sind auch Objektreferenzen Werte, welche speziell sind: Wenn die Funktion die Eigenschaften eines referenzierte Objekts ändern, ist die Änderung außerhalb der Funktion sichtbar, wie im folgenden Beispiel gezeigt wird:</p>
<pre class="brush: js notranslate">/* Deklariert die Funktion 'myFunc' */
function myFunc(theObject) {
theObject.brand = "Toyota";
}
/*
* Deklariert die Variable 'mycar';
* Erstellt und initialisiert ein neues Objekt;
* Weist Referenz 'mycar' zu
*/
var mycar = {
brand: "Honda",
model: "Accord",
year: 1998
};
/* gibt 'Honda' aus */
console.log(mycar.brand);
/* Übergibt Objektreferenz der Funktion */
myFunc(mycar);
/*
* gibt 'Toyota' als Wert der 'brand' Eigenschaft
* des Objektes aus, so wie er von der Funktion geändert wurde.
*/
console.log(mycar.brand);
</pre>
<p>Das <a href="/de/docs/Web/JavaScript/Reference/Operators/this"><code>this</code> Schlüsselwort</a> referenziert nicht zum aktuell ausgeführten Funktion, so, dass man das <code>Function</code> Objekt über den Namen referenzierten muss, auch im Funktionskörper.</p>
<h2 id="Funktionen_definieren">Funktionen definieren</h2>
<p>Es gibt verschiedenen Möglichkeiten Funktionen zu definieren:</p>
<h3 id="Die_Funktionsdeklaration_function_Statement">Die Funktionsdeklaration (<code>function</code> Statement)</h3>
<p>Es gibt eine spezielle Syntax für das Deklarieren von Funktionen (siehe <a href="/de/docs/Web/JavaScript/Reference/Statements/function">Funktionsstatement</a> für mehr Details):</p>
<pre class="syntaxbox notranslate">function <em>name</em>([<em>param</em>[, <em>param</em>[, ... <em>param</em>]]]) {
<em>statements</em>
}
</pre>
<dl>
<dt><code>name</code></dt>
<dd>Der Funktionsname.</dd>
</dl>
<dl>
<dt><code>param</code></dt>
<dd>Der Name eines Arguments, welches der Funktion übergeben wird. Eine Funktion kann bis zu 255 Argumente haben.</dd>
</dl>
<dl>
<dt><code>statements</code></dt>
<dd>Die Statements, welche den Funktionskörper der Funktion bilden.</dd>
</dl>
<h3 id="Der_Funktionsausdruck_function_Ausdruck">Der Funktionsausdruck (<code>function</code> Ausdruck)</h3>
<p>Ein Funktionsausdruck ist ähnlich wie eine Funktionsdeklaration und hat die selbe Syntax (siehe <a href="/de/docs/Web/JavaScript/Reference/Operators/function">Funktionsausdruck</a> für Details). Ein Funktionsausdruck ist manchmal ein Teil eines größeren Ausdrucks. Man kann benannte Funktionsausdrücke (in denen der Name des Ausdrucks zum Beispiel im Aufrufstack benutzt wird) oder anonyme Funktionsausdrücke definieren. Funktionsausdrücke werden nicht an den Anfang des Gültigkeitsbereiches verschoben (<em>hoisted</em>), was bedeutet, dass sie nicht vor der Definition im Code benutzt werden können.</p>
<pre class="syntaxbox notranslate">function [<em>name</em>]([<em>param</em>[, <em>param</em>[, ... <em>param</em>]]]) {
<em>statements</em>
}
</pre>
<dl>
<dt><code>name</code></dt>
<dd>Der Funktionsname. Kann weggelassen werden, wodurch die Funktion eine sogenannte anonyme Funktion ist.</dd>
</dl>
<dl>
<dt><code>param</code></dt>
<dd>Der Name eines Arguments, welches der Funktion übergeben wird. Eine Funktion kann bis zu 255 Argumente haben.</dd>
<dt><code>statements</code></dt>
<dd>Die Statements, welche den Funktionskörper der Funktion bilden.</dd>
</dl>
<p>Hier ist ein Beispiel für einen <strong>anonymen</strong> Funktionsausdruck (<code>name</code> wird nicht benutzt):</p>
<pre class="brush: js notranslate">var myFunction = function() {
statements
}</pre>
<p>Es ist auch möglich den Namen in der Funktionsdefinition erreichbar zu machen, indem eine <strong>benannter</strong> Funktionsausdruck erstellt wird:</p>
<pre class="brush: js notranslate">var myFunction = function namedFunction(){
statements
}
</pre>
<p>Ein Vorteil beim Erstellen eines benannten Funktionsausdrucks ist, dass im Fall eines auftretenden Fehlers, der Name der Funktion im Stack Trace enthalten ist, was es einfacher macht den Ursprung des Fehlers zu finden.</p>
<p>Wie gezeigt, beginnen beide Beispiele nicht mit dem <code>function</code> Schlüsselwort. Statements die Funktionen enthalten aber nicht mit <code>function</code> beginnen, sind Funktionsausdrücke.</p>
<p>Wenn eine Funktion nur einmal benutzt wird, wird ein Pattern namens <strong>IIFE (<em>Immediately Invokable Function Expression</em>)</strong> genutzt.</p>
<pre class="brush: js notranslate">(function() {
statements
})();</pre>
<p>IIFE sind Funktionsausdrücke, die direkt nach dem Definieren ausgeführt werden.</p>
<h3 id="Die_Generatorfunktionendeklaration_function*_Statement">Die Generatorfunktionendeklaration (<code>function*</code> Statement)</h3>
<p>Es gibt eine spezielle Syntax für die Deklaration von Generatorfunktionen (siehe {{jsxref('Statements/function*', 'function* Statement')}} für Details):</p>
<pre class="syntaxbox notranslate">function* <em>name</em>([<em>param</em>[, <em>param</em>[, ... <em>param</em>]]]) {
<em>statements</em>
}
</pre>
<dl>
<dt><code>name</code></dt>
<dd>Der Funktionsname.</dd>
</dl>
<dl>
<dt><code>param</code></dt>
<dd>Der Name eines Arguments, welches der Funktion übergeben wird. Eine Funktion kann bis zu 255 Argumente haben.</dd>
</dl>
<dl>
<dt><code>statements</code></dt>
<dd>Die Statements, welche den Funktionskörper der Funktion bilden.</dd>
</dl>
<h3 id="Der_Generatorfunktionsausdruck_function*_Ausdruck">Der Generatorfunktionsausdruck (<code>function*</code> Ausdruck)</h3>
<p>Ein Generatorfunktionsausdruck ist ähnlich wie eine Generatorfunktionsdeklaration und hat die selbe Syntax (siehe {{jsxref('Operators/function*', 'function* expression')}} für Details):</p>
<pre class="syntaxbox notranslate">function* [<em>name</em>]([<em>param</em>[, <em>param</em>[, ... <em>param</em>]]]) {
<em>statements</em>
}
</pre>
<dl>
<dt><code>name</code></dt>
<dd>Der Funktionsname. Kann weggelassen werden, wodurch die Funktion eine sogenannte anonyme Funktion ist.</dd>
</dl>
<dl>
<dt><code>param</code></dt>
<dd>Der Name eines Arguments, welches der Funktion übergeben wird. Eine Funktion kann bis zu 255 Argumente haben.</dd>
<dt><code>statements</code></dt>
<dd>Die Statements, welche den Funktionskörper der Funktion bilden.</dd>
</dl>
<h3 id="Der_Pfeilfunktionsausdruck_>">Der Pfeilfunktionsausdruck (=>)</h3>
<p>Eine Pfeilfunktionsausdruck hat eine kürzere Syntax und der <code>this</code> Wert ist lexikalisch gebunden (siehe <a href="/de/docs/Web/JavaScript/Reference/Functions/Pfeilfunktionen">Pfeilfunktionen</a> für Details):</p>
<pre class="syntaxbox notranslate">([param[, param]]) => {
statements
}
param => expression
</pre>
<dl>
<dt><code>param</code></dt>
<dd>Der Name eines Arguments. Keine Argumente müssen mit <code>()</code> angegeben werden. Für nur ein Argument sind die Klammern nicht notwendig (z. B. <code>foo => 1</code>).</dd>
<dt><code>statements or expression</code></dt>
<dd>Mehrere Statements müssen in Klammern geschrieben werden. Ein einziger Ausdruck benötigt keine Klammern. Dieser Ausdruck ist implizit der Rückgabewert der Funktion.</dd>
</dl>
<h3 id="Der_Function_Konstruktor">Der <code>Function</code> Konstruktor</h3>
<div class="note">
<p><strong>Hinweis:</strong> Der Einsatz des <code>Function</code> Konstruktors, um eine Funktion zu erstellen wird nicht empfohlen, weil der Funktionskörper als String übergeben wird, welcher von einigen JS Engines nicht optimiert werden kann und zu Problemen führen kann.</p>
</div>
<p>Wie alle anderen Objekte, können {{jsxref("Function")}} Objekte mit dem <code>new</code> Operator erstellt werden:</p>
<pre class="syntaxbox notranslate">new Function (<em>arg1</em>, <em>arg2</em>, ... <em>argN</em>, <em>functionBody</em>)
</pre>
<dl>
<dt><code>arg1, arg2, ... arg<em>N</em></code></dt>
<dd>Null oder mehr Namen, welche von der Funktion als formale Parameter benutzt werden. Jeder muss ein valider JavaScript Bezeichner sein.</dd>
</dl>
<dl>
<dt><code>functionBody</code></dt>
<dd>Ein String, der die JavaScript Statements enthält, die den Funktionskörper formen.</dd>
</dl>
<p>Das Ausführen des <code>Function</code> Konstruktors als Funktion (ohne den Einsatz des <code>new</code> Operators) hat den selben Effekt wie das Aufrufen als Konstruktor.</p>
<h3 id="Der_GeneratorFunction_Konstruktor">Der <code>GeneratorFunction</code> Konstruktor</h3>
<div class="note">
<p><strong>Hinweis:</strong> <code>GeneratorFunction</code> ist kein globales Objekt, kann aber von Generatorfunktionsinstanzen erhalten werden (siehe {{jsxref("GeneratorFunction")}} für mehr Details).</p>
</div>
<div class="note">
<p><strong>Hinweis:</strong> Der Einsatz des <code>GeneratorFunction</code> Konstruktors, um eine Funktion zu erstellen wird nicht empfohlen, weil der Funktionskörper als String übergeben wird, welcher von einigen JS Engines nicht optimiert werden kann und zu Problemen führen kann.</p>
</div>
<p>Wie alle anderen Objekte, können {{jsxref("GeneratorFunction")}} Objekte mit dem <code>new</code> Operator erstellt werden:</p>
<pre class="syntaxbox notranslate">new GeneratorFunction (<em>arg1</em>, <em>arg2</em>, ... <em>argN</em>, <em>functionBody</em>)
</pre>
<dl>
<dt><code>arg1, arg2, ... arg<em>N</em></code></dt>
<dd>Null oder mehr Namen, welche von der Funktion als formale Parameter benutzt werden. Jeder muss ein valider JavaScript Bezeichner sein oder eine Liste solcher Strings mit Komma getrennt. Zum Beispiel "<code>x</code>", "<code>theValue</code>", or "<code>a,b</code>".</dd>
</dl>
<dl>
<dt><code>functionBody</code></dt>
<dd>Ein String, der die JavaScript Statements enthält, die den Funktionskörper formen.</dd>
</dl>
<p>Das Ausführen des <code>GeneratorFunction </code>Konstruktors als Funktion (ohne den Einsatz des <code>new</code> Operators) hat den selben Effekt wie das Aufrufen als Konstruktor.</p>
<h2 id="Funktionsparameter">Funktionsparameter</h2>
<h3 id="Standardparameter">Standardparameter</h3>
<p>Standard Funktionsparameter erlauben es formale Parameter mit einem Standardwert zu initialisieren, wenn kein Wert oder <code>undefined</code> übergeben wird. Für mehr Details siehe <a href="/de/docs/Web/JavaScript/Reference/Functions/Default_parameters">Standardparameter</a>.</p>
<h3 id="Rest_Parameter">Rest Parameter</h3>
<p>Die Rest Parameter Syntax erlaubt die Repräsentation von beliebig fielen Argumenten als ein Array. Für mehr Details siehe <a href="/de/docs/Web/JavaScript/Reference/Functions/rest_parameters">Rest Parameter</a>.</p>
<h2 id="Das_arguments_Objekt">Das <code>arguments</code> Objekt</h2>
<p>Man kann die Funktionsargumente in einer Funktion referenzieren, indem das <code>arguments</code> Objekt benutzt wird. Siehe <a href="/de/docs/Web/JavaScript/Reference/Functions/arguments">arguments</a>.</p>
<ul>
<li><code><a href="/de/docs/JavaScript/Reference/Functions_and_function_scope/arguments">arguments</a></code>: Ein arrayähnliches Objekt, welches die übergebenen Argumente in der aktuell ausgeführten Funktion enthält.</li>
<li><code><a href="/de/docs/JavaScript/Reference/Functions_and_function_scope/arguments/callee">arguments.callee</a></code> {{Deprecated_inline}}: Die aktuell ausgeführte Funktion.</li>
<li><code><a href="/de/docs/JavaScript/Reference/Functions_and_function_scope/arguments/caller">arguments.caller</a></code> {{Obsolete_inline}} : Die Funktion, die die aktuell ausgeführte Funktion aufgerufen hat.</li>
<li><code><a href="/de/docs/JavaScript/Reference/Functions_and_function_scope/arguments/length">arguments.length</a></code>: Die Anzahl der Argumente, die der Funktion übergeben wurden.</li>
</ul>
<h2 id="Methodenfunktionen_definieren">Methodenfunktionen definieren</h2>
<h3 id="Getter_und_Setter_Funktionen">Getter und Setter Funktionen</h3>
<p>Man kann Getter (Zugriffsmethoden) und Setter (Änderungsmethoden) bei jedem Standardobjekt oder benutzerdefinierten Objekt, welches das Hinzufügen von neuen Eigenschaften unterstützt. Die Syntax für das Definieren von Gettern und Settern beim Einsatz der Objektliteralsyntax.</p>
<dl>
<dt><a href="/de/docs/Web/JavaScript/Reference/Functions/get">get</a></dt>
<dd>
<p>Bindet eine Objekteigenschaft an eine Funktion, welche aufgerufen wird, wenn der Wert der Eigenschaft abgefragt wird.</p>
</dd>
<dt><a href="/de/docs/Web/JavaScript/Reference/Functions/set">set</a></dt>
<dd>Bindet eine Objekteigenschaft an eine Funktion, welche aufgerufen wird, wenn der Wert der Eigenschaft geändert wird.</dd>
</dl>
<h3 id="Methodendefinitionssyntax">Methodendefinitionssyntax</h3>
<p>Angefangen mit ECMAScript 2015 kann man eigene Methoden in einer kürzeren Syntax, ähnlich wie Getter und Setter, definieren. Siehe <a href="/de/docs/Web/JavaScript/Reference/Functions/Method_definitions">Methodendefinition</a> für mehr Details.</p>
<pre class="brush: js notranslate">var obj = {
foo() {},
bar() {}
};</pre>
<h2 id="Konstruktor_vs._Deklaration_vs._Ausdruck">Konstruktor vs. Deklaration vs. Ausdruck</h2>
<p>Das folgende wird verglichen:</p>
<p>Eine Funktion, die mit dem <code>Function</code> Konstruktor definiert wird und der Variablen <code>multiply</code> zugewiesen wird:</p>
<pre class="brush: js notranslate">var multiply = new Function('x', 'y', 'return x * y');</pre>
<p>Eine Funktionsdeklaration mit dem Namen <code>multiply</code>:</p>
<pre class="brush: js notranslate">function multiply(x, y) {
return x * y;
} // there is no semicolon here
</pre>
<p>Ein Funktionsausdruck einer anonymen Funktion, die der Variablen <code>multiply</code> zugewiesen wird:</p>
<pre class="brush: js notranslate">var multiply = function(x, y) {
return x * y;
};
</pre>
<p>Ein Funktionsausdruck der Funktion <code>func_name</code>, die der Variablen <code>multiply</code> zugewiesen wird:</p>
<pre class="brush: js notranslate">var multiply = function func_name(x, y) {
return x * y;
};
</pre>
<h3 id="Unterschiede">Unterschiede</h3>
<p>Alle machen annähernd die selben Dinge, jedoch mit kleinen subtilen Unterschieden:</p>
<p>Es gibt einen Unterschied zwischen dem Funktionsnamen und der Variable, der die Funktion zugewiesen wird. Der Funktionsnamen kann nicht geändert werden, während die Variable, die mit der Funktion zugewiesen ist, überschrieben werden kann. Der Funktionsname kann nur innerhalb des Funktionskörpers benutzt werden. Der Versuch diesen außerhalb des Funktionskörpers zu benutzen resultiert in einem Fehler (oder <code>undefined</code>, wenn der Funktionsname vorher mit einem <code>var</code> Statement deklariert wurde). Zum Beispiel:</p>
<pre class="brush: js notranslate">var y = function x() {};
alert(x); // Führt zu einem Error
</pre>
<p>Der Funktionsname taucht auch auf, wenn die Funktion mit der <a href="/de/docs/Web/JavaScript/Reference/Global_Objects/Function/toString">toString Methode</a> serialisiert wird.</p>
<p>Auf der anderen Seite ist die Variable, der die Funktion zugewiesen ist, nur durch ihren Gültigkeitsbereich begrenzt, der garantiert den Geltungsbereich einschließt, in dem die Funktion deklariert ist.</p>
<p>Wie das 4. Beispiel zeigt, kann sich der Funktionsname von dem Namen der Variablen, der die Funktion zugewiesen ist, unterscheiden. Diese sind nicht voneinander abhängig. Eine Funktionsdeklaration erstellt ebenfalls eine Variable mit dem selben Namen wie die Funktion. Im Gegensatz zu den durch Funktionsausdrücke definierten Funktionen können Funktionen, die durch Funktionsdeklarationen definiert sind, über ihren Namen in dem Bereich aufgerufen werden, in dem sie definiert wurden:</p>
<p>Eine Funktionsdefinition mit '<code>new Function'</code> hat keinen Funktionsnamen. In der <a href="/de/docs/Mozilla/Projects/SpiderMonkey">SpiderMonkey</a> JavaScript Engine haben solche Funktionen in serialisierter Form immer den Namen "anonymous". Zum Beispiel gibt <code>alert(new Function())</code> folgendes aus:</p>
<pre class="brush: js notranslate">function anonymous() {
}
</pre>
<p>Weil die Funktion aktuell keinen Namen hat, ist <code>anonymous</code> keine Variable, die in der Funktion erreicht werden kann. Zum Beispiel führt folgendes zu einem Fehler:</p>
<pre class="brush: js notranslate">var foo = new Function("alert(anonymous);");
foo();
</pre>
<p>Anders als Funktionsdefinitionen mit Funktionsausdrücken oder dem <code>Function</code> Konstruktor, kann eine Funktionsdefinition mit Funktionsdeklaration genutzt werden, bevor bevor sie deklariert wird. Zum Beispiel:</p>
<pre class="brush: js notranslate">foo(); // alerts FOO!
function foo() {
alert('FOO!');
}
</pre>
<p>Eine Funktionsdefinition mit einem Funktionsausdruck oder einer Funktionsdeklaration erbt den aktuellen Gültigkeitsbereich. Das bedeutet, die Funktion bildet eine Closure. Auf der anderen Seite erbt eine Funktion, die mit dem <code>Function</code> Konstruktor definiert wird, keinen anderen Gültigkeitsbereich außer dem globalen (welchen alle Funktionen erben).</p>
<pre class="brush: js notranslate">/*
* Declare and initialize a variable 'p' (global)
* and a function 'myFunc' (to change the scope) inside which
* declare a varible with same name 'p' (current) and
* define three functions using three different ways:-
* 1. function declaration
* 2. function expression
* 3. function constructor
* each of which will log 'p'
*/
var p = 5;
function myFunc() {
var p = 9;
function decl() {
console.log(p);
}
var expr = function() {
console.log(p);
};
var cons = new Function('\tconsole.log(p);');
decl();
expr();
cons();
}
myFunc();
/*
* Logs:-
* 9 - for 'decl' by function declaration (current scope)
* 9 - for 'expr' by function expression (current scope)
* 5 - for 'cons' by Function constructor (global scope)
*/
</pre>
<p>Funktionsdefinitionen als Funktionsausdrücke und Funktionsdeklarationen werden nur einmal übersetzt, während das bei <code>Function</code> Konstruktoren nicht so ist. Das bedeutet, dass der Funktionskörper, der dem <code>Function</code> Konstruktor übergeben wird, mit jedem Aufruf des Konstruktors erneut übersetzt wird. Weil ein Funktionsausdruck jedes mal eine Closure erstellt und der Funktionskörper aber nicht erneut übersetzt wird, sind Funktionsausdrücke um einiges schneller als "<code>new Function(...)</code>". Deshalb sollte der <code>Function</code> Konstruktor überall vermieden werden, wo es geht.</p>
<p>Es sollte bemerkt werden, dass immer wenn Funktionsausdrücke und Funktionsdeklarationen verschachtelt in einer Funktion generiert vom <code>Function</code> Konstruktor erstellt werden, sie nicht mehrfach übersetzt werden. Zum Beispiel:</p>
<pre class="brush: js notranslate">var foo = (new Function("var bar = \'FOO!\';\nreturn(function() {\n\talert(bar);\n});"))();
foo(); // The segment "function() {\n\talert(bar);\n}" of the function body string is not re-parsed.</pre>
<p>Eine Funktionsdeklaration wird sehr einfach (und oft unabsichtlich) in einen Funktionsausdruck geändert. Eine Funktionsdeklaration hört auf eine zu sein, wenn:</p>
<ul>
<li>sie ein Teil eines Ausdrucks wird</li>
<li>sie kein "source element" einer Funktion oder des Skriptes selbst ist. Ein "source element" ist ein nicht geschachteltes Statement im Skript oder eines Funktionskörpers:</li>
</ul>
<pre class="brush: js notranslate">var x = 0; // source element
if (x === 0) { // source element
x = 10; // not a source element
function boo() {} // not a source element
}
function foo() { // source element
var y = 20; // source element
function bar() {} // source element
while (y === 10) { // source element
function blah() {} // not a source element
y++; // not a source element
}
}
</pre>
<h3 id="Beispiele">Beispiele</h3>
<pre class="brush: js notranslate">// Funktionsdeklaration
function foo() {}
// Funktionsausdruck
(function bar() {})
// Funktionsausdruck
x = function hello() {}
if (x) {
// Funktionsausdruck
function world() {}
}
// Funktionsdeklaration
function a() {
// Funktionsdeklaration
function b() {}
if (0) {
// Funktionsausdruck
function c() {}
}
}
</pre>
<h2 id="Funktionen_als_Block-Level-Element">Funktionen als Block-Level-Element</h2>
<p>Beginnend mit ES2015 sind Funktionen im <a href="/de/docs/Web/JavaScript/Reference/Strict_mode">strict Modus</a> an den Block gebunden. Vor ES2015 waren Funktionen auf Blockebene im strikten Modus verboten.</p>
<pre class="brush: js notranslate">'use strict';
function f() {
return 1;
}
{
function f() {
return 2;
}
}
f() === 1; // true
// f() === 2 nicht im strict Modus
</pre>
<h3 id="Block-level_Funktionen_im_nicht-strict_Code">Block-level Funktionen im nicht-strict Code</h3>
<p>Kurz gesagt: nicht machen.</p>
<p>Im nicht strict Code verhalten sich Funktionsdeklarationen innerhalb von Blöcken merkwürdig. Zum Beispiel:</p>
<pre class="brush: js notranslate">if (shouldDefineZero) {
function zero() { // DANGER: compatibility risk
console.log("This is zero.");
}
}
</pre>
<p>ES2015 besagt, dass wenn <code>shouldDefineZero</code> false ist, <code>zero</code> niemals definiert wird, weil der Block nie ausgeführt wird. Jedoch ist das ein neuer Teil des Standards. Historisch war dieser Teil unspezifiziert und einigen Browser definierten <code>zero</code> egal, ob der Block ausgeführt wurde oder nicht.</p>
<p>Im <a href="/de/docs/Web/JavaScript/Reference/Strict_mode">strict Modus</a> verhalten sich alle Browser, die ES2015 unterstützen, gleich. <code>zero</code> wird nur Definiert wenn <code>shouldDefineZero</code> true ist und nur in dem Gültigkeitsbereich des <code>if</code>-Blocks.</p>
<p>Ein sicherer Weg eine Funktion bedingt zu definieren ist es einen Funktionsausdruck einer Variablen zuzuweisen:</p>
<pre class="brush: js notranslate">var zero;
if (shouldDefineZero) {
zero = function() {
console.log("This is zero.");
};
}
</pre>
<h2 id="Beispiele_2">Beispiele</h2>
<h3 id="Zurückgeben_einer_formatierten_Zahl">Zurückgeben einer formatierten Zahl</h3>
<p>Die folgende Funktion gibt einen String zurück, der eine formatierte Zahlenrepräsentation mit führenden Nullen enthält.</p>
<pre class="brush: js notranslate">// This function returns a string padded with leading zeros
function padZeros(num, totalLen) {
var numStr = num.toString(); // Initialize return value as string
var numZeros = totalLen - numStr.length; // Calculate no. of zeros
for (var i = 1; i <= numZeros; i++) {
numStr = "0" + numStr;
}
return numStr;
}
</pre>
<p>Die folgende Statements rufen die padZeros Funktion auf.</p>
<pre class="brush: js notranslate">var result;
result = padZeros(42,4); // returns "0042"
result = padZeros(42,2); // returns "42"
result = padZeros(5,4); // returns "0005"
</pre>
<h3 id="Prüfen_ob_eine_Funktoin_vorhanden_ist">Prüfen, ob eine Funktoin vorhanden ist</h3>
<p>Man kann prüfen, ob eine Funktion existiert, indem man den <code>typeof</code> Operator benutzt wird. Im folgenden Beispiel wird getestet, ob das Objekt <code>window</code> eine Eigenschaft mit dem Namen <code>noFunc</code> hat, die eine Funktion ist. Wenn das so ist, wird sie benutzt, andernfalls wird etwas anderes gemacht.</p>
<pre class="brush: js notranslate"> if ('function' === typeof window.noFunc) {
// use noFunc()
} else {
// do something else
}
</pre>
<p>Zu beachten ist, dass im <code>if</code> Test eine Referenz zu <code>noFunc</code> benutzt wird — es stehen keine Klammern <code>()</code> nach dem Funktionsnamen, so dass die Funktion nicht aufgerufen wird.</p>
<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('ES1')}}</td>
<td>{{Spec2('ES1')}}</td>
<td>Initiale Definition. Implementiert in JavaScript 1.0</td>
</tr>
<tr>
<td>{{SpecName('ES5.1', '#sec-13', 'Function Definition')}}</td>
<td>{{Spec2('ES5.1')}}</td>
<td></td>
</tr>
<tr>
<td>{{SpecName('ES6', '#sec-function-definitions', 'Function definitions')}}</td>
<td>{{Spec2('ES6')}}</td>
<td>Neu: Pfeilfunktionen, Generatorfunktionen, Standardparameter, Rest Parameter.</td>
</tr>
<tr>
<td>{{SpecName('ESDraft', '#sec-function-definitions', 'Function definitions')}}</td>
<td>{{Spec2('ESDraft')}}</td>
<td></td>
</tr>
</tbody>
</table>
<h2 id="Browserkompatibilität">Browserkompatibilität</h2>
<p>{{Compat("javascript.functions")}}</p>
<h2 id="Siehe_auch">Siehe auch</h2>
<ul>
<li>{{jsxref("Statements/function", "Funktionsstatement")}}</li>
<li>{{jsxref("Operators/function", "Funktionsausdruck")}}</li>
<li>{{jsxref("Statements/function*", "function* Statement")}}</li>
<li>{{jsxref("Operators/function*", "function* Ausdruck")}}</li>
<li>{{jsxref("Function")}}</li>
<li>{{jsxref("GeneratorFunction")}}</li>
<li>{{jsxref("Functions/Arrow_functions", "Pfeilfunktionen")}}</li>
<li>{{jsxref("Functions/Default_parameters", "Standardparameter")}}</li>
<li>{{jsxref("Functions/rest_parameters", "Rest Parameter")}}</li>
<li>{{jsxref("Functions/arguments", "Arguments Objekt")}}</li>
<li>{{jsxref("Functions/get", "Getter")}}</li>
<li>{{jsxref("Functions/set", "Setter")}}</li>
<li>{{jsxref("Functions/Method_definitions", "Methodendefinitionen")}}</li>
<li><a href="/de/docs/Web/JavaScript/Reference/Functions_and_function_scope">Funktionen und Funktionsgültigkeitsbereiche</a></li>
</ul>
|