Funktionen
Funktionen
- Deklaration einer Funktion
- mit dem Schlüsselwort
function - als Funktionsausdruck mit
function - als Funktionsausdruck mit dem
=>-Operator - mit dem Konstruktor
Function
function add1(a, b) { return a + b; }
let add2 = function (a, b) { return a + b; }
let add3 = (a, b) => a + b;
let add4 = new Function('a', 'b', 'return a + b');
- Funktionen sind Objekte
- sie können über Variablen referenziert werden
- sie können an andere Funktionen übergeben werden
- sie haben Attribute
- Aufruf einer Funktion
- über ihren Namen mit dem
()-Operator - über eine Variable, die auf die Funkion zeigt mit
() - über die
apply- odercall-Methode, die jede Funktion hat
- Parameterübergabe wie in Java
- pass-by-value: Kopie der Parameter wird angelegt
- formale Parameter sind lokale Variable
- bei Objekten wird die Referenz kopiert, nicht das Objekt
- Rückgabe von Werten
- Rückgabe-Parameter wird nicht deklariert
- Schlüsselwort
returnfür Rückgabe - Funktionen können Funktionen enthalten
Funktionen deklarieren
- Deklaration (function declaration)
function f() { } - Benannter Funktionsausdruck (named function expression)
let f = function f() { }; - Anonyme Funktion (anonymous function)
let f = function() { }; - Literal (function literal)
let f = () => 23;
Beispiel: Funktionen deklarieren
function f1() { }
let f2 = function() { };
let f3 = function f3() { };
log(f1.name);
log(f2.name);
log(f3.name);
Unterschiede bei der Deklaration
- Deklarierte Funktionen sind auch vor der Deklaration sichtbar
- Anonyme und benannte Funktionen erst ab der Zuweisung
log(typeof sumDek);
function sumDek(a, b) { return a + b; }
log(typeof sumAnon); // nicht verfügbar
let sumAnon = function(a, b) { return a + b; };
log(typeof sumAnon);
Beispiel: Funktionen deklarieren
function add(a, b) {
let result = a + b;
return result;
}
let sub = function(a, b) {
return a - b;
};
// Funktionskonstruktor
let mul = new Function("a", "b", "return a * b;");
Beispiel: Funktionen aufrufen
// Zuweisung des Funktionsobjektes
let subtract = sub;
let addiere = add;
// Aufruf einer Funktion
let i = add(3, 5); log(i);
let j = sub(7, 4); log(j);
let k = subtract(12, 6); log(k);
let l = addiere(12, 6); log(l);
let m = add.apply(null, new Array(7, 9)); log(m);
Beispiel: Funktionen in Funktionen
function aussen(a, b) {
function innen(c) {
return a + c;
}
return innen(b);
}
let m = aussen(3, 4);
log(m);
Beispiel: Vararg Funktionen
function varag(...rest) {
let summe = 0;
for (let n of rest) {
summe += n;
}
return summe;
}
let n = varag(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
log(n);
Default-Values
Parameter einer Funktion können mit Default-Werten belegt werden
function sum(a, b, c = 0) {
return a + b + c;
}
log(sum(1, 2));
log(sum(1, 2, 3));
Beispiel: Übergabe einer Funktion
let add = function(a, b) { return a + b; };
let sub = function(a, b) { return a - b; };
function calc(operation, a, b) {
return operation(a, b);
}
let o = calc(add, 4, 2); log(o);
let p = calc(sub, 4, 2); log(p);
Funktionen als Objekte
Funktionen sind Objekte mit Properties und Methoden
length: Anzahl der Parameter (ohne Varag-Parameter)name: Name der Funktion bei der Deklarationprototype: Prototypen-Objekt zur Funktion (s. u.)call(o, p1, p1, ...): Ruft die Funktion mit dem Objektoalsthisaufapply(o, args): Ruft die Funktion mit dem ObjektoalsthisauftoString(): Gibt die Deklaration der Funktion zurück
function add(a, b) { return a + b; }
let x = add;
log(x.name);
log(x.apply(null, [ 1, 2 ]));
log(x.call(null, 1, 2));
log(x.toString());
Immediate Functions
- Funktionen können direkt bei der Deklaration aufgerufen werden: immediate functions
- Kann dazu genutzt werden, den Namensraum sauber zu halten
(function(person) {
let greeting = 'Hello ';
log(greeting + person);
}('Thomas'));
Eingebaute Funktionen
Beispiele für eingebaute Funktionen
eval(string): interpretiert übergebenen String als CodeisFinite(wert): prüft auf gültigen WertebereichisNaN(wert): prüft auf ungültigen WertebereichparseFloat(string): in Fließkommazahl umwandelnparseInt(string): String in Ganzzahl umwandeln
Beispiele für eingebaute Funktionen
Number(wert): In Zahl umwandelnString(wert): in Zeichenkette umwandelnencodeURI(string): in URI-Format umwandelndecodeURI(string): aus URI-Format umwandelnZahl.toFixed(n): n Nachkommastellen erzwingen
Beispiel: Eingebaute Funktionen
let a = eval("2 + 5");
log(a);
let b = 0.0 / 0.0;
log(isFinite(b));
log(isNaN(b));
let c = parseFloat("24.42") - 1.0;
log(c);
let e = String(5) + "0";
log(e);
let f = encodeURI("Ein String / Strung");
log(f);
let g = 42;
let h = g.toFixed(5);
log(h);
Closure
Eine Funktion kann eine andere Funktion erzeugen
- der Erzeuger kann lokale Variablen haben
- der Erzeugte kann auf diese zugreifen
- der Erzeugte lebt länger als der Erzeuger
- was passiert mit den lokalen Variablen?
Antwort
- die erzeugte Funktion merkt sich den Kontext im Augenblick ihrer Erstellung (closure)
- dieser lebt dann solange, wie die erzeugte Funktion
- Closures speichern nicht den Wert, sondern eine Referenz darauf
Beispiel: Closure
function erzeuger() {
let wert = 41;
return function() {
return wert + 1;
};
}
// "wert" ist nicht sichtbar
let erzeugter = erzeuger();
log(erzeugter());
Das Problem mit this
- Innerhalb einer inneren Funktion zeigt
thisnicht auf das Objekt der äußeren Funktion - Design-Fehler von JavaScript
let o = {
k: 42,
f: function() {
function inner() { log(this.k); }
inner();
}};
o.f();
1. Lösung: Variable self selbst anlegen
let o = {
k: 42,
f: function() {
let self = this;
function inner() { log(self.k); }
inner();
}};
o.f();
2. Lösung: Funktionsliteral verwenden
let o = {
k: 42,
f: function() {
let inner = () => log(this.k);
inner();
}};
o.f();