-
Notifications
You must be signed in to change notification settings - Fork 17
/
funktionen.html
189 lines (180 loc) · 15.3 KB
/
funktionen.html
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
<!DOCTYPE html>
<html lang="de">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>JavaScript: Funktionen</title>
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" href="js-doku.css">
<script src="js-doku.js"></script>
</head>
<body>
<div id="nav">
<p>Hier entsteht eine <strong>JavaScript-Dokumentation</strong> von <a href="http://molily.de/">molily</a>. Derzeit ist sie noch lückenhaft, wächst aber nach und nach. Kommentare und Feedback werden gerne per <a href="mailto:zapperlott@gmail.com">E-Mail</a> entgegen genommen.</p>
<p class="contents-link"><a href="./">Zum Inhaltsverzeichnis</a></p>
</div>
<h1>JavaScript: Funktionen</h1>
<div class="section" id="function">
<h2>Einführung</h2>
<p>Mit Funktionen können Sie flexible Teilprogramme notieren.</p>
<p>... Das haben Sie sicher schon im Grundlagenkurs Programmierung gelernt, oder kennen es schon von anderen Programmiersprachen. ...</p>
<p>Die vorgegebenen JavaScript-Objekte bieten in erster Linie Funktionen, die Sie in Ihren Scripten aufrufen können.</p>
<p>In JavaScript spielen Funktionen einen höheren Stellenwert als in anderen Programmiersprachen und haben einige Besonderheiten - deshalb spricht man davon, dass JavaScript Aspekte einer <em>funktionalen Programmiersprache</em> besitzt. In JavaScript sind Funktionen nicht einfach feste, einmal definierte Script-Bestandteile, sondern selbst Objekte, mit denen man im Script nahezu ungehindert arbeiten kann. Sie können sogar problemlos neue Funktionen zur Laufzeit erzeugen und einmal
definierte wieder löschen.</p>
<p>Wenn Sie <strong>eigene Funktionen definieren</strong>, so können Sie sie an bestimmte andere Objekte hängen. Das bedeutet, sie als Unterobjekte eines Objektes zu speichern. In diesem Fall spricht man in der Terminologie der objektorientierten Programmierung von einer <strong>Methode</strong>. In anderen Fällen ist es sinnvoller, die Funktion als lokale Variable in einer anderen Funktion anzulegen. Und schließlich brauchen Sie die Funktion gar nicht zu speichern - sie können Sie auch
anonym (namenlos) anlegen, nur um sie z.B. als Parameter an eine andere Funktion weiterzugeben. Diese drei Möglichkeiten werden Ihnen später noch klarer werden, wenn wir betrachten, auf welche Weise Sie Funktionen erzeugen können.</p>
</div>
<div class="section" id="deklarationen">
<h2>Funktionsdeklarationen</h2>
<p>Es gibt drei Arten, wie Sie Funktionen notieren und damit Funktionsobjekte erzeugen können. Die einfachste und wichtigste Art ist die sogenannte Funktions-Deklaration (auf englisch <em>function declaration</em>). Deren Syntax ist folgendermaßen aufgebaut:</p>
<pre>function <var>Funktionsname</var> (<var>Parameterliste</var>) {
<var>Anweisungen</var>
}</pre>
<p>Der <strong>Funktionsname</strong> muss <a href="objekte-variablen.html#bezeichner">den üblichen Anforderungen an JavaScript-Bezeichner</a> genügen: Sie dürfen Buchstaben, Zahlen und einige Sonderzeichen (das Dollar-Zeichen, den Unterstrich ... TODO) verwenden. Der Funktionsname darf in diesem Fall aber keine Leerzeichen enthalten. TODO: Wann darf er das?</p>
<p>Die <strong>Parameterliste</strong> zwischen den beiden runden Klammern ist eine durch Kommas getrennte Liste von Namen. Für diese gelten die besagten Namenskonventionen. Unter den in dieser Auflistung vergebenen Namen können Sie innerhalb der Funktion auf die übergebenen Parameter zugreifen.</p>
<p>Zwischen den beiden geschweiften Klammern wird der sogenannte Funktionskörper notiert: Darin werden die <a href="syntax.html#anweisungen">Anweisungen</a> untergebracht, die beim Aufruf der Funktion ausgeführt werden sollen.</p>
<p>Folgendes Beispiel soll das Schema verdeutlichen:</p>
<pre>function statusMeldung (meldungsTyp, meldungsText) {
var ausgabeElement = document.getElementById("meldungsausgabe");
ausgabeElement.className = meldungsTyp;
ausgabeElement.innerHTML = meldungsText;
}
statusMeldung("fehler", "Beim Absenden Ihrer Nachricht ist ein Fehler aufgetreten. " +
"Bitte versuchen Sie es erneut."); </pre>
<p>Das Beispiel definiert eine Funktion mit dem Namen <code>statusMeldung</code>. Die Funktion erwartet zwei Parameter mit dem Namen <code>meldungsTyp</code> bzw. <code>meldungsText</code>.</p>
<p>Die Funktion wird nach dem Schema <code><var>Funktionsname</var>(<var>Parameterliste</var>)</code> aufgerufen. Die beiden runden Klammern nach dem Funktionsnamen sind der eigentliche</p>
<p>...</p>
<p>Was passiert: wenn Sie direkt in einem script-Element notieren, wird eine globale Funktion angelegt. Das ist eine Methode des window-Objektes ... Globale Variablen sind wiederum nichts anderes als Eigenschaften des Objektes <code>window</code>.</p>
<p>bla() = window.bla()! window["bla"]!</p>
</div>
<div class="section" id="parameter">
<h2>Funktionsparameter</h2>
<p>Bei der Deklaration weisen Sie den Funktionsparametern </p>
<pre>function Summe (zahl1, zahl2, zahl3) {
}
Summe(5, 10, 15);</pre>
<p></p>
</div>
<div class="section" id="arguments">
<h2>Variable Parameterzahl: Der arguments-Array</h2>
<p></p>
</div>
<div class="section" id="ergebnis">
<h2>Rückgabewert (Ergebnis)</h2>
<p>return</p>
</div>
<div class="section" id="lokale-variablen">
<h2>Lokale Variablen (Funktionsvariablen)</h2>
<p>Gültigkeitsbereich (Scope)</p>
</div>
<div class="section" id="ausdruecke">
<h2>Funktionsausdrücke</h2>
<p>Wie gesagt gibt es neben der oben vorgestellten zwei weitere, also insgesamt drei Schreibweisen, mit denen Sie Funktionen erzeugen können. Je nach Verwendungszweck können die folgenden weniger bekannten Schreibweisen passender sein.</p>
<p>Die zweite Art, wie Sie Funktionen notieren können, ist der sogenannte <strong>Funktions-Ausdruck</strong> (englisch <em>function expression</em>). Diese Schreibweise hat viele Vorteile, Sie werden sie schätzen lernen und vielfältig anwenden können.</p>
<p>Um den Unterschied zwischen Funktionsdeklaration und Funktionsausdruck zu verstehen, müssen Sie den Unterschied zwischen <a href="syntax.html#anweisungen"><em>Anweisungen</em></a> (Statements) und <a href="syntax.html#ausdruecke"><em>Ausdrücken</em></a> (Expressions) kennen. Die vorgestellte Funktionsdeklaration ist nämlich eine Anweisung, der Funktionsausdruck hingegen ein Ausdruck. Damit haben beide unterschiedliche Anwendungsmöglichkeiten. Sie können Funktionsausdrücke an viel mehr Stellen notieren als eine Funktionsdeklaration.</p>
<p>Das Schema eines Funktionsausdruckes sieht folgendermaßen aus:</p>
<pre>function (<var>Parameterliste</var>) { <var>Anweisungen</var> }</pre>
<p>Ein solcher Funktionsausdruck selbst ergibt lediglich eine Funktion, speichert Sie aber nicht unter einem Namen. Man spricht daher auch von <strong>anonymen (namenlosen)</strong> Funktionen.</p>
<p>Das Ergebnis des Ausdruckes, ein Funktionsobjekt, können Sie jedoch weiterverwenden. Beispielsweise können Sie das erzeugte Funktionsobjekt in einer Variable speichern:</p>
<pre>var <var>Funktionsname</var> = function (<var>Parameterliste</var>) { <var>Anweisungen</var> };
</pre>
<p>Dieses Variablenzuweisung mit Funktionsausdruck hat denselben Effekt wie die klassische Funktionsdeklaration <code>function <var>Funktionsname</var> (...) {...}</code>. Das bedeutet, sie sind unter allen Umständen austauschbar.</p>
<p>Darüber lässt sich auch genauer verstehen, was eine Funktionsdeklaration macht. Wenn die gleichwertigen Anweisungen innerhalb einer Funktion notiert werden, wird eine <em>lokale Variable</em> erzeugt, in der die neue Funktion gespeichert wird. Stehen sie außerhalb einer Funktion ausgeführt, dann wird eine <em>globale Variable</em> erzeugt, das heißt die neue Funktion wird als Methode von Objektes <code>window</code> angelegt.</p>
<p>Was sind nun die <strong>Vorteile</strong> eines Funktionsausdruckes?</p>
<p>Mit Funktionsdeklarationen erzeugt man üblicherweise globale Funktionen (<code>window</code>-Methoden). Wenn Sie eine Funktion mittels Funktionsausdruck erzeugen, müssen Sie diese nicht zwangsläufig global als <code>window</code>-Methode abspeichern, sondern können sie auch an einem anderen Objekt speichern. Auf diese Weise können Sie Ordnung in Ihre Scripte bringen und zusammenhörige Variablen z.B. unter einem Objekt gruppieren. Ein Beispiel:</p>
<pre>var bildergalerie = new Object();
bildergalerie.abspielen = function () {
/* ... */
};
bildergalerie.abspielen();</pre>
<p>Im obigen Beispiel wird eine leere <a href="kernobjekte.html#object"><code>Object</code>-Instanz</a> erzeugt, die als globale Variable mit dem Namen <code>bildergalerie</code> gespeichert wird. In der zweiten Zeile wird dem zunächst leeren Objekt eine Methode hinzugefügt. Die entsprechende Funktion wird mithilfe eines Funktionsausdrucks notiert. Das entstehende Funktionsobjekt wird in der Eigenschaft <code>abspielen</code> gespeichert (siehe <a href="kernobjekte.html#object-hashes">Object-Objekte als Zuordnungslisten</a>). In der dritten Zeile schließlich wird diese Funktion aufgerufen.</p>
<p>Die Gruppierung unter dem Objekt <code>bildergalerie</code> hat den Vorteil, dass der globale Gültigkeitsbereich, das <code>window</code>-Objekt, nicht übermäßig mit eigenen Objekten beschrieben wird. Der Verzicht auf globale Variablen hat den Vorteil, dass mehrere Scripte problemlos zusammenarbeiten können. [TODO: Diese Programmiertechnik der Kapselung zentral beschreiben.]</p>
<p>Im Beispiel wird lediglich das Objekt <code>bildergalerie</code> global gespeichert, das heißt als Eigenschaft von <code>window</code>. Folglich darf an keiner anderen Stelle eine gleichnamige globale Variable erzeugt werden, sonst würde das Objekt überschrieben werden. Die Funktion <code>abspielen</code> hängt hingegen als Methode am <code>bildergalerie</code>-Objekt. Sie kann anderen, gleichnamigen Funktionen nicht in die Quere kommen.</p>
<p>...</p>
<p>Eine weitere häufige Anwendung von Funktionsausdrücken findet sich im <strong>Event-Handling</strong>. Um eine Handler-Funktionen zu notieren, können Sie herkömmliche Funktionsdeklarationen nutzen:</p>
<pre>// Handler-Funktion mit Funktionsdeklaration notieren
function init () {
window.alert("Dokument ist fertig geladen!");
}
// Event-Handler registrieren
window.onload = init;</pre>
<p>Im Beispiel wird eine globale Funktion namens <code>init</code> angelegt und daraufhin als Event-Handler für das <code>load</code>-Ereignis beim <code>window</code>-Objekt registriert (siehe <a href="einbindung.html#traditionelles-event-handling">traditionelles Event-Handling</a>).</p>
<p>Diese Schreibweise ergibt Sinn, wenn Sie die Funktion <code>init</code> später noch einmal benötigen. Üblicherweise ist das nicht der Fall: Man braucht solche Funktionen nur an der Stelle, wo man sie als Handler registriert; es ist nicht nötig, sie irgendwo unter einem Namen zu speichern.</p>
<p>In diesem Fall kann ein Funktionsausdruck den Code vereinfachen. Notieren Sie die Handler-Funktion mit einem Ausdruck und speichern Sie sie direkt in der <code>onload</code>-Eigenschaft:</p>
<pre>window.onload = function () {
window.alert("Dokument ist fertig geladen!");
};</pre>
<p>Dasselbe Prinzip können Sie überall beim <a href="konzepte.html#events">Event-Handling</a> anwenden. Wenn Sie beispielsweise einem Element einen <code>click</code>-Handler zuweisen wollen, so könnten Sie die fragliche Funktion mit einer Deklaration notieren:</p>
<pre>function klickHandler () {
window.alert("Element wurde geklickt!");
}
document.getElementById("bla").onclick = klickHandler;</pre>
<p>Üblicherweise besteht keine Notwendigkeit, die Handler-Funktion global unter dem Namen »klickHandler« <!-- TODO --> zu speichern. Stattdessen können Sie einen Funktionsausdruck verwenden und die erzeugte Funktion direkt als <code>click</code>-Handler abspeichern:</p>
<pre>document.getElementById("bla").onclick = function () {
window.alert("Element wurde geklickt!");
};</pre>
<p>Es gibt noch viele weitere Fälle, in denen das Zwischenspeichern einer Funktion, wie es eine Funktionsdeklaration zwangsläufig tut, unnötig ist - und damit gibt es es zahlreiche weitere Anwendungsmöglichkeiten für Funktionsausdrücke. Im Abschnitt über Closures werden wir darauf zurückkommen.</p>
</div>
<div class="section" id="function-konstruktor">
<h2>Function-Konstruktor</h2>
<p>Wenden wir uns der dritten und letzten Möglichkeit zur Erzeugung von Funktionen zu. Dieser brauchen Sie keine große Aufmerksamkeit schenken, denn ihr Anwendungsbereich ist klein und ihr Gebrauch entsprechend selten.</p>
<p>Alle Funktionen, egal wie sie erzeugt wurden, sind Instanzen des <code>Function</code>-Konstruktors. Sie können daher auch direkt diesen Konstruktor aufrufen, um eine weitere Instanz zu erzeugen. Die Schreibweise lautet folgendermaßen:</p>
<pre>new Function("Anweisungen", "Parametername1", "Parametername2", ...)</pre>
<p>Sie rufen Function mit dem Schlüsselwort <code>new</code> auf. Der Konstruktor erwartet die Anweisungen, d.h. den Funktionskörper, im ersten Parameter. Dabei muss es sich um einen <strong>String</strong> handeln! Der zweite, dritte und alle folgenden Parameter enthalten die Parameternamen der neuen Funktion - ebenfalls als Strings. Wenn die zu erzeugende Funktion drei Parameter namens ...</p>
<p>Der Aufruf von <code>new Function(...)</var></code> erzeugt lediglich eine Funktion, speichert sie selbst aber noch nicht. Sie kennen das bereits vom Funktionsausdruck. Möchten Sie die erzeugte Funktion in einer lokalen Variable speichern, können Sie notieren:</p>
<pre>var quadrat = new Function(
// Funktionskörper mit Anweisungen
"window.alert('Das Quadrat der Zahl ' + zahl + 'lautet: ' + (zahl * zahl);",
// Name des ersten Parameters
"zahl"
);
// Aufruf der erzeugten Funktion
quadrat(5);</pre>
<p></p>
<!-- TODO ?: <p>var Funktionsname</p>-->
<p>Diese recht umständliche Notationsweise macht nur dann Sinn, wenn Sie in Ihrem JavaScript-Programm JavaScript-Code als String gespeichert haben und eine Funktion daraus machen wollen. Dies kommt freilich nur in einigen Spezialanwendungen vor.</p>
<p>Verwenden Sie nach Möglichkeit die beschriebenen Funktionsdeklarationen und -ausdrücke.</p>
</div>
<div class="section" id="closures">
<h2>Verschachtelte Funktionen (Closures)</h2>
<p>Fortgesch</p>
<p>siehe Artikel</p>
<p></p>
<pre>
function meineFunktion () {
document.getElementBy
}
window.setTimeout(meineFunktion, 5000);
function irgendeineFunktion () {
var bla = "string"; // diese Variable ist nur in dieser Funktion verfügbar
var status = 50;
setTimeout(
function () {
// Verschachtelte Funktion
// Closure!
alert(status);
},
5000
);
}</pre>
</div>
<div class="section" id="funktional">
<h2>Funktionale Programmierg: Funktionen als Objekte verwenden</h2>
<p>Funktionen sind ganz normale Objekte mit Eigenschaften und Methoden</p>
<p>Event-Handler und Callback-Funktionen</p>
<p>Funktionale Programmierung</p>
</div>
<div class="section" id="this">
<h2>Kontext einer Funktion: Das Schlüsselwort this</h2>
<p>Kontext mit call und apply beeinflussen</p>
</div>
<div class="section" id="...">
<h2>...</h2>
<p>...</p>
</div>
<div id="footer">
<p><strong>JavaScript-Dokumentation</strong> · <a href="./">Zum Inhaltsverzeichnis</a></p>
<p>Autor: <a href="http://molily.de/">molily</a> · Kontakt: <a href="mailto:zapperlott@gmail.com">zapperlott@gmail.com</a></p>
<p>Lizenz: <a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/de/">Creative Commons Namensnennung - Weitergabe unter gleichen Bedingungen</a>.</p>
</div>
</body>
</html>