1
0
Fork 0
mirror of https://github.com/TheTaz25/denis.ergin.git synced 2025-07-06 21:58:48 +00:00

feat(slides): add slides for js-functions

This commit is contained in:
Denis Ergin 2024-12-18 17:05:47 +01:00
parent 44d5becbd1
commit 90431c90db
5 changed files with 249 additions and 0 deletions

View file

@ -0,0 +1,83 @@
<section>
<section>
<h2>Funktionen Deklarieren</h2>
</section>
<section>
<p>Wie in anderen Sprachen helfen uns Funktionen einzelne Aufgaben in einer abgekapselten Umgebung auszuführen.</p>
<p>Wie bereits in der Einführung zu JavaScript erklärt, sind Funktionen "First-Class". Funktionen werden wir andere Objekte / Variablen behandelt.</p>
</section>
<section>
<p>Eine Funktion wird in JS mit dem keyword <code>function</code> und dem zu vergebenen Namen deklariert.</p>
<p>Parameter werden danach in Runden Klammern mit Kommas getrennt verfasst.</p>
<p>Zuletzt folgt in geschweiften Klammern der eigentliche Code der in der Funktion ausgeführt werden soll.</p>
</section>
<section>
<p>Fangen wir doch mit etwas an, um Inhalte "formattierter" ins document zu schreiben.</p>
<pre class="js"><code data-trim data-line-numbers is:raw>
function writeParagraph(contents) {
document.writeln(`&lt;p&gt;${contents}&lt;/p&gt;`);
}
</code></pre>
</section>
<section>
<p>Wenn etwas berechnet und zurück gegeben werden soll, kann man das keyword <code>return</code> verwenden.</p>
<pre class="js"><code data-trim data-line-numbers is:raw>
function square(toSquare) {
return toSquare * toSquare;
}
</code></pre>
</section>
<section>
<h3>Arrow Functions</h3>
</section>
<section>
<p>Neben der Deklaration mit dem keyword, kann man auch eine sogenannte <code>Arrow-Function</code> definieren und einer Variable zuweisen:</p>
<pre class="js"><code data-trim data-line-numbers is:raw>
const square = (toSquare) =&gt; {
return toSquare * toSquare;
}
</code></pre>
</section>
<section>
<p>Wenn wir einen Wert direkt zurückgeben können, benötigen wir keine geschweiften Klammern und das <code>return</code> keyword.</p>
<pre class="js"><code data-trim data-line-numbers is:raw>
const square = (toSquare) =&gt; toSquare * toSquare;
</code></pre>
</section>
<section>
<h3>Function Overloading</h3>
</section>
<section>
<p>Es ist in JavaScript <strong>nicht</strong> möglich, Funktionen zu überladen.</p>
<p>Wenn wir eine Variable Anzahl an Parametern zulassen wollen, müssen wir manche davon ignorieren / miteinbeziehen.</p>
<p>Generell eignet es sich aus Sicht eines Entwicklers aber dedizierte Funktionen für solche Sonderfälle zu implementieren.</p>
</section>
<section>
<h3>Default Parameter</h3>
</section>
<section>
<p>Wenn wir einen Default-Parameter angeben wollen, der optional mitgegeben werden kann, können wir in der Parameterliste einen mit einem Gleichheitszeichen definieren</p>
<pre><code data-trim data-line-numbers is:raw>
function wrapIntoElement(content, tag = 'div') {
return `&lt;${tag}&gt;${content}&lt;/${tag}&gt;`;
}
// "&lt;div&gt;hello&lt;/div&gt;"
console.log(wrapIntoElement('hello'));
// "&lt;p&gt;hello&lt;/p&gt;"
console.log(wrapIntoElement('hello', 'p'));
</code></pre>
</section>
</section>

View file

@ -0,0 +1,11 @@
---
import Title from './title.astro';
import FunctionDeclaration from './function-definition.astro';
import Scope from './scope.astro';
---
<div class="slides">
<Title />
<FunctionDeclaration />
<Scope />
</div>

View file

@ -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 &amp; 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>&amp; 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 &amp; 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) =&gt; (b) =&gt; 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>

View file

@ -0,0 +1,3 @@
<section>
<h1>Javascript <br>Funktionen</h1>
</section>

View file

@ -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>