diff --git a/src/components/slides/javascript/03-functions/function-definition.astro b/src/components/slides/javascript/03-functions/function-definition.astro
new file mode 100644
index 0000000..51763e9
--- /dev/null
+++ b/src/components/slides/javascript/03-functions/function-definition.astro
@@ -0,0 +1,83 @@
+ Wie in anderen Sprachen helfen uns Funktionen einzelne Aufgaben in einer abgekapselten Umgebung auszuführen. Wie bereits in der Einführung zu JavaScript erklärt, sind Funktionen "First-Class". Funktionen werden wir andere Objekte / Variablen behandelt. Eine Funktion wird in JS mit dem keyword Parameter werden danach in Runden Klammern mit Kommas getrennt verfasst. Zuletzt folgt in geschweiften Klammern der eigentliche Code der in der Funktion ausgeführt werden soll. Fangen wir doch mit etwas an, um Inhalte "formattierter" ins document zu schreiben. Wenn etwas berechnet und zurück gegeben werden soll, kann man das keyword Neben der Deklaration mit dem keyword, kann man auch eine sogenannte Wenn wir einen Wert direkt zurückgeben können, benötigen wir keine geschweiften Klammern und das Es ist in JavaScript nicht möglich, Funktionen zu überladen. Wenn wir eine Variable Anzahl an Parametern zulassen wollen, müssen wir manche davon ignorieren / miteinbeziehen. Generell eignet es sich aus Sicht eines Entwicklers aber dedizierte Funktionen für solche Sonderfälle zu implementieren. Wenn wir einen Default-Parameter angeben wollen, der optional mitgegeben werden kann, können wir in der Parameterliste einen mit einem Gleichheitszeichen definierenFunktionen Deklarieren
+ function
und dem zu vergebenen Namen deklariert.
+
+ function writeParagraph(contents) {
+ document.writeln(`<p>${contents}</p>`);
+ }
+
return
verwenden.
+
+ function square(toSquare) {
+ return toSquare * toSquare;
+ }
+
Arrow Functions
+ Arrow-Function
definieren und einer Variable zuweisen:
+
+ const square = (toSquare) => {
+ return toSquare * toSquare;
+ }
+
return
keyword.
+
+ const square = (toSquare) => toSquare * toSquare;
+
Function Overloading
+ Default Parameter
+
+
+ function wrapIntoElement(content, tag = 'div') {
+ return `<${tag}>${content}</${tag}>`;
+ }
+
+ // "<div>hello</div>"
+ console.log(wrapIntoElement('hello'));
+
+ // "<p>hello</p>"
+ console.log(wrapIntoElement('hello', 'p'));
+
Wenn wir bisher Funktionen und Variablen definiert haben, haben wir das in einem "globalen" Bereich getan. Funktionen und andere Mechanismen konnte "frei" auf diese Inhalte zugreifen und ggf modifizieren.
+Sie waren im "Scope" der Nutzenden Funktion.
+Eine Funktion kann generell auf alle Variablen des äußeren Scopes zugreifen.
+Umgekehrt kann man nicht "von außen" auf Variablen innerhalb einer Funktion zugreifen oder diese ändern.
+Wie sieht das nun in der Praxis aus?
+
+ let multiplikator = 2;
+
+ function multiply (value) {
+ return multiplikator++ * value;
+ }
+
+ function add (value) {
+ return multiplikator + value;
+ }
+
+ // 10
+ console.log(multiply(5));
+ // 11
+ console.log(add(8));
+
+ Die Funktion multiply
greift auf die Variable außerhalb zu und kann diese auch modifizieren (Nach den Regeln der JavaScript Variablen).
Andere Funktionen sind von dieser Änderung betroffen.
+In diesem Fall ist die Variable multiplikator
im globalen Scope und die Funktionen multiply & add
können darauf zugreifen.
+ function multiplyBy5 (value) {
+ const mySecret = 5;
+ return value * mySecret;
+ }
+
+ // Add kann nun nicht auf die Konstante "mySecret"
+ // in multiplyBy5 zugreifen
+ function add (value) {
+ console.log(mySecret);
+ return 42 + value;
+ }
+
+ Wir können Funktionen innerhalb anderer Funktionen definieren. Die innere Funktion ist dann nur in der äußeren Funktion aufrufbar.
+Somit generieren wir auch eine "Closure": Eine Funktion mit Variablen zusammen mit einer Umgebung die dieses Variablen "bindet".
+
+ function summierer() {
+ let summe = 0;
+ function summieren(value) {
+ summe += value;
+ return summe;
+ }
+ return summieren;
+ }
+
+ const alleSummen = summierer();
+ console.log(alleSummen(5)); // 5
+ console.log(alleSummen(5)); // 10
+ console.log(alleSummen(5)); // 15
+ console.log(alleSummen(5)); // 20
+
+ Wusstet Ihr das...
+Wir auf die Implementierung der Definierten Funktionen mit toString()
zugreifen können?
Das bedeutet wir können somit auf Variablen innerhalb einer Funktion zugreifen (und damit auslesen)...
+Was wenn wir das nicht wollen?
+Wir können eine unbenamte Funktion erstellen und sofort aufrufen. Die Definition innerhalb dieser Funktion kann nicht mehr erreicht werden, sobald wir im außerhalb liegenden "Scope" liegen.
+Aber wir können innerhalb dieser Funktion weitere Funktionen definieren und diese zurückgeben.
+Probiert es hiermit mal aus:
+
+ // Die "()()"-Syntax ruft die Funktion in der ersten Klammer sofort auf.
+ const petCreator = (function() {
+ let name = '';
+
+ function setName(newName) {
+ name = newName;
+ }
+
+ return { setName };
+ })();
+
+ In modernen Bibliotheken und Frameworks wird diese Art zu schreiben weniger benötigt, aber in "Vanilla-JS" ist das eine gute Möglichkeit Funktionalitäten nach Domänen zu kapseln.
+Es benötigt etwas Erfahrung um Einschätzen zu können, ob & wann man IIFE's nutzen soll.
+Wenn wir innerhalb einer Funktion eine Funktion zurück geben und das gegebenenfalls öfters machen, so nennt man dieses Verfahren "Currying".
+Typisch für Currying ist, dass die inneren Funktionen irgendwann Parameter aus den äußeren Funktionen verwenden.
+
+ const add = (a) => (b) => a + b;
+
+ // 10
+ console.log(add(5)(5));
+
+ Wir können das Verfahren zum Beispiel dann verwenden, wenn wir an mehreren Stellen im Code Parameter in eine Funktion packen wollen um am Ende ein Ergebnis zu erhalten.
+