From 90431c90dbf953a23c3ee5838a8af93ba2223383 Mon Sep 17 00:00:00 2001 From: Denis Ergin Date: Wed, 18 Dec 2024 17:05:47 +0100 Subject: [PATCH] feat(slides): add slides for js-functions --- .../03-functions/function-definition.astro | 83 ++++++++++ .../javascript/03-functions/index.astro | 11 ++ .../javascript/03-functions/scope.astro | 144 ++++++++++++++++++ .../javascript/03-functions/title.astro | 3 + .../slides/javascript/03-functions.astro | 8 + 5 files changed, 249 insertions(+) create mode 100644 src/components/slides/javascript/03-functions/function-definition.astro create mode 100644 src/components/slides/javascript/03-functions/index.astro create mode 100644 src/components/slides/javascript/03-functions/scope.astro create mode 100644 src/components/slides/javascript/03-functions/title.astro create mode 100644 src/pages/slides/javascript/03-functions.astro 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 @@ +
+
+

Funktionen Deklarieren

+
+ +
+

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 function und dem zu vergebenen Namen deklariert.

+

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.

+

+      function writeParagraph(contents) {
+        document.writeln(`<p>${contents}</p>`);
+      }
+    
+
+ +
+

Wenn etwas berechnet und zurück gegeben werden soll, kann man das keyword return verwenden.

+

+      function square(toSquare) {
+        return toSquare * toSquare;
+      }
+    
+
+ +
+

Arrow Functions

+
+ +
+

Neben der Deklaration mit dem keyword, kann man auch eine sogenannte Arrow-Function definieren und einer Variable zuweisen:

+

+      const square = (toSquare) => {
+        return toSquare * toSquare;
+      }
+    
+
+ +
+

Wenn wir einen Wert direkt zurückgeben können, benötigen wir keine geschweiften Klammern und das return keyword.

+

+      const square = (toSquare) => toSquare * toSquare;
+    
+
+ +
+

Function Overloading

+
+ +
+

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.

+
+ +
+

Default Parameter

+
+ +
+

Wenn wir einen Default-Parameter angeben wollen, der optional mitgegeben werden kann, können wir in der Parameterliste einen mit einem Gleichheitszeichen definieren

+

+      function wrapIntoElement(content, tag = 'div') {
+        return `<${tag}>${content}</${tag}>`;
+      }
+
+      // "<div>hello</div>"
+      console.log(wrapIntoElement('hello'));
+
+      // "<p>hello</p>"
+      console.log(wrapIntoElement('hello', 'p'));
+    
+
+
\ No newline at end of file diff --git a/src/components/slides/javascript/03-functions/index.astro b/src/components/slides/javascript/03-functions/index.astro new file mode 100644 index 0000000..cb16bbe --- /dev/null +++ b/src/components/slides/javascript/03-functions/index.astro @@ -0,0 +1,11 @@ +--- +import Title from './title.astro'; +import FunctionDeclaration from './function-definition.astro'; +import Scope from './scope.astro'; +--- + +
+ + <FunctionDeclaration /> + <Scope /> +</div> \ No newline at end of file diff --git a/src/components/slides/javascript/03-functions/scope.astro b/src/components/slides/javascript/03-functions/scope.astro new file mode 100644 index 0000000..e200c42 --- /dev/null +++ b/src/components/slides/javascript/03-functions/scope.astro @@ -0,0 +1,144 @@ +<section> + <section> + <h2>Scope</h2> + </section> + + <section> + <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.</p> + <p>Sie waren im "Scope" der Nutzenden Funktion.</p> + </section> + + <section> + <p>Eine Funktion kann generell auf alle Variablen des äußeren Scopes zugreifen.</p> + <p>Umgekehrt kann man nicht "von außen" auf Variablen innerhalb einer Funktion zugreifen oder diese ändern.</p> + </section> + + <section> + <p>Wie sieht das nun in der Praxis aus?</p> + <pre class="js"><code data-trim data-line-numbers is:raw> + 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)); + </code></pre> + </section> + + <section> + <p>Die Funktion <code>multiply</code> greift auf die Variable außerhalb zu und kann diese auch modifizieren (Nach den Regeln der JavaScript Variablen).</p> + <p>Andere Funktionen sind von dieser Änderung betroffen.</p> + <p>In diesem Fall ist die Variable <code>multiplikator</code> im globalen Scope und die Funktionen <code>multiply & add</code> können darauf zugreifen.</p> + </section> + + <section> + <pre class="js"><code data-trim data-line-numbers is:raw> + 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; + } + </code></pre> + </section> + + <section> + <h3>Nested Functions <br>& Closures</h3> + </section> + + <section> + <p>Wir können Funktionen innerhalb anderer Funktionen definieren. Die innere Funktion ist dann nur in der äußeren Funktion aufrufbar.</p> + <p>Somit generieren wir auch eine "Closure": Eine Funktion mit Variablen zusammen mit einer Umgebung die dieses Variablen "bindet".</p> + </section> + + <section> + <pre class="js"><code data-trim data-line-numbers is:raw> + 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 + </code></pre> + </section> + + <section> + <p>Wusstet Ihr das...</p> + <p>Wir auf die Implementierung der Definierten Funktionen mit <code>toString()</code> zugreifen können?</p> + <p>Das bedeutet wir können somit auf Variablen innerhalb einer Funktion zugreifen (und damit auslesen)...</p> + <p>Was wenn wir das nicht wollen?</p> + </section> + + <section> + <h3>Immediately Invoked Function Expressions (IIFE)</h3> + </section> + + <section> + <p>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.</p> + <p>Aber wir können innerhalb dieser Funktion weitere Funktionen definieren und diese zurückgeben.</p> + </section> + + <section> + <p>Probiert es hiermit mal aus:</p> + <pre class="js"><code data-trim data-line-numbers is:raw> + // Die "()()"-Syntax ruft die Funktion in der ersten Klammer sofort auf. + const petCreator = (function() { + let name = ''; + + function setName(newName) { + name = newName; + } + + return { setName }; + })(); + </code></pre> + </section> + + <section> + <p>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.</p> + <p>Es benötigt etwas Erfahrung um Einschätzen zu können, ob & wann man IIFE's nutzen soll.</p> + </section> + + <section> + <h3>Function Currying</h3> + </section> + + <section> + <p>Wenn wir innerhalb einer Funktion eine Funktion zurück geben und das gegebenenfalls öfters machen, so nennt man dieses Verfahren "Currying".</p> + <p>Typisch für Currying ist, dass die inneren Funktionen irgendwann Parameter aus den äußeren Funktionen verwenden.</p> + </section> + + <section> + <pre class="js"><code data-trim data-line-numbers is:raw> + const add = (a) => (b) => a + b; + + // 10 + console.log(add(5)(5)); + </code></pre> + </section> + + <section> + <p>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.</p> + </section> +</section> \ No newline at end of file diff --git a/src/components/slides/javascript/03-functions/title.astro b/src/components/slides/javascript/03-functions/title.astro new file mode 100644 index 0000000..b220d85 --- /dev/null +++ b/src/components/slides/javascript/03-functions/title.astro @@ -0,0 +1,3 @@ +<section> + <h1>Javascript <br>Funktionen</h1> +</section> \ No newline at end of file diff --git a/src/pages/slides/javascript/03-functions.astro b/src/pages/slides/javascript/03-functions.astro new file mode 100644 index 0000000..e5d7c2b --- /dev/null +++ b/src/pages/slides/javascript/03-functions.astro @@ -0,0 +1,8 @@ +--- +import Reveal from "../../../layouts/Reveal.astro"; +import Slides from "../../../components/slides/javascript/03-functions/index.astro"; +--- + +<Reveal title="JavaScript - Functions"> + <Slides /> +</Reveal> \ No newline at end of file