From 482a095e1eb9ffd81d6c34d376ce1562ccb73575 Mon Sep 17 00:00:00 2001 From: Sascha Schulz <sschulz@dh-software.de> Date: Mo, 17 Jul 2023 10:36:37 +0200 Subject: [PATCH] Merge branch 'draft' --- index.html | 479 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 479 insertions(+), 0 deletions(-) diff --git a/index.html b/index.html index 92d3368..d31dd79 100644 --- a/index.html +++ b/index.html @@ -2125,6 +2125,485 @@ </code> </pre> </section> + <section> + <h3>this</h3> + <pre> + <code class="js" data-trim data-line-numbers> + class MyClass { + constructor(a) { + this.a = a; + } + + getA() { + return this.a; + } + } + + const x = new MyClass(5); + const y = new MyClass(10); + + console.log(x.getA()); + console.log(y.getA()); + </code> + </pre> + <pre> + <code class="bash" data-trim data-line-numbers> + 5 + 10 + </code> + </pre> + </section> + <section> + <pre> + <code class="js" data-trim data-line-numbers> + global.a = 5; + + function foo() { + this.a += 10; + } + + foo(); + + console.log(a); + </code> + </pre> + <pre> + <code class="bash" data-trim data-line-numbers> + 15 + </code> + </pre> + </section> + <section> + <pre> + <code class="js" data-trim data-line-numbers> + class MyClass { + /* ... */ + setA() { + function f() { + this.a += 100; + } + f(); + } + } + + const x = new MyClass(5); + + x.setA(); + + console.log(x.getA()); + </code> + </pre> + <pre> + <code class="bash" data-trim data-line-numbers> + TypeError: Cannot read property 'a' of undefined + </code> + </pre> + </section> + <section> + <pre> + <code class="js" data-trim data-line-numbers> + class MyClass { + /* ... */ + setA() { + const me = this; + function f() { + me.a += 100; + } + f(); + } + } + + const x = new MyClass(5); + + x.setA(); + + console.log(x.getA()); + </code> + </pre> + <pre> + <code class="bash" data-trim data-line-numbers> + 105 + </code> + </pre> + </section> + <section> + <h3>Arrow-Funktionen</h3> + <ul> + <li>Kompakte Schreibweise einer normalen Funktion</li> + <li>Bei Einzeilern ist das <code>return</code> nicht notwendig</li> + <li>this-Pointer des aktuellen Kontextes wird beibehalten</li> + </ul> + <pre> + <code class="js" data-trim data-line-numbers> + // Einzeiler + const f1 = _ => 1; + const f2 = () => 1; + const f3 = (x) => x * x; + const f4 = (x, y) => x + y; + + // Mehrzeiler + const f5 = (x, y) => { + return x * y; + }; + </code> + </pre> + </section> + <section> + <pre> + <code class="js" data-trim data-line-numbers> + class MyClass { + /* ... */ + setA() { + const f = () => { + this.a += 100; + } + f(); + } + } + + const x = new MyClass(5); + + x.setA(); + + console.log(x.getA()); + </code> + </pre> + <pre> + <code class="bash" data-trim data-line-numbers> + 105 + </code> + </pre> + </section> + <section> + <h3>Generator-Funktionen</h3> + <pre> + <code class="js" data-trim data-line-numbers> + function* generator() { + let i = 0; + + while(true) { + yield i; + i++; + } + } + + const g = generator(); + + console.log(g.next().value); + console.log(g.next().value); + console.log(g.next().value); + </code> + </pre> + <pre> + <code class="bash" data-trim data-line-numbers> + 1 + 2 + 3 + </code> + </pre> + </section> + <section> + <h3>Generator-Funktionen</h3> + <pre> + <code class="js" data-trim data-line-numbers> + function* generator() { + yield 1; + yield 2; + yield 3; + } + + const g = generator(); + + for (const i of g) { + console.log(i); + } + </code> + </pre> + <pre> + <code class="bash" data-trim data-line-numbers> + 1 + 2 + 3 + </code> + </pre> + </section> + <section> + <h3>Nützliche Array-Funktionen</h3> + </section> + <section> + Aufgabe: Schreibe ein Programm, das den Gesamtumsatz aus dem ersten Halbjahr berechnet + <pre> + <code class="js" data-trim data-line-numbers> + const revenues = [ + {month: 0, revenue: 1000}, + {month: 1, revenue: 2000}, + {month: 2, revenue: 3000}, + {month: 3, revenue: 4000}, + {month: 4, revenue: 5000}, + {month: 5, revenue: 6000}, + {month: 6, revenue: 6000}, + {month: 7, revenue: 5000}, + {month: 8, revenue: 4000}, + {month: 9, revenue: 3000}, + {month: 10, revenue: 2000}, + {month: 11, revenue: 1000} + ]; + + let totalRevenue = 0; + + /* ... */ + + console.log(totalRevenue); + </code> + </pre> + </section> + <section> + Lösung + <pre> + <code class="js" data-trim data-line-numbers> + totalRevenue = revenues + .filter((revenue) => revenue.month < 6) + .map((revenue) => revenue.amount) + .reduce((sum, amount) => sum + amount, 0); + </code> + </pre> + <pre> + <code class="bash" data-trim data-line-numbers> + 21000 + </code> + </pre> + </section> + <section> + <pre> + <code class="js" data-trim data-line-numbers> + const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + + a.filter((e) => e > 2); // Filterung + a.map((e) => e * 2); // Umformung + a.reduce((p, e) => p + e, 0); // Zusammenrechnung / Reduzierung + a.some((e) => e > 5); // true wenn min. ein Element die Bedingung erfüllt + a.every((e) => e > 5); // true wenn alle Elemente die Bedingung erfüllen + </code> + </pre> + </section> + <section> + <h3>Map</h3> + <ul> + <li>auch als "assoziatives Array" bezeichnet</li> + <li>iterierbare Liste</li> + <li>ideal zur Assoziation von z.B. Hashes zu Objekt-Instanzen o.ä.</li> + <li>nutzbar ab es6 / es2015</li> + <li>löst herkömmliche Objekte als Hash-Map ab</li> + </ul> + </section> + <section> + <pre> + <code class="js" data-trim data-line-numbers> + const m = new Map(); + + m.set("a", 0); + m.set("a", 1); + m.set("b", 2); + + m.has("c"); // => false + + m.delete("b"); + + console.log(m.get("a")); // => 1 + </code> + </pre> + </section> + <section> + <pre> + <code class="js" data-trim data-line-numbers> + m.forEach((k, v) => console.log(k, v)) // => "a" 1 ... + + for (const entry of m.entries()) { + console.log(entry); // => ["a", 1] ... + } + + for (const key of m.keys()) { + console.log(key); // => "a" ... + } + + for (const value of m.values()) { + console.log(value); // => "1" ... + } + </code> + </pre> + </section> + <section> + <h3>Set</h3> + <ul> + <li>enthält nur einzigartige Werte</li> + <li>iterierbare Liste</li> + <li>ideale Struktur, wenn einzelne Werte einzigartig sein sollen</li> + <li>nutzbar ab es6 / es2015</li> + <li>löst individuelle Lösungen mittels Arrays und Array.prototype.indexOf o.ä. ab</li> + </ul> + </section> + <section> + <pre> + <code class="js" data-trim data-line-numbers> + const s = new Set(); + + s.add("a"); + s.add("a"); + + s.has("c"); // => false + + s.delete("a"); + + console.log(s.size); // => 0 + </code> + </pre> + </section> + <section> + <pre> + <code class="js" data-trim data-line-numbers> + s.forEach((k, v) => console.log(k, v)) // => "a" "a" ... + + for (const entry of m.entries()) { + console.log(entry); // => ["a", "a"] ... + } + + for (const key of m.keys()) { + console.log(key); // => "a"... + } + + for (const value of s.values()) { + console.log(value); // => "a" ... + } + </code> + </pre> + </section> + <section> + <h3>DOM-Events</h3> + <ul> + <li>funktionale Ausführung von Code</li> + <li>Trigger können Klicks, Scrollen, Tastendrücke, Änderungen der Fenstergröße usw. sein</li> + </ul> + </section> + <section> + <img data-src="/assets/images/dom-events.svg"> + </section> + <section> + <pre> + <code class="js" data-trim data-line-numbers> + function doSomething(e) { + console.log("capture"); + } + + function click(e) { + console.log("bubble"); + } + + div.addEventListener("click", doSomething, true); + + button.addEventListener("click", click, false /* default */); + </code> + </pre> + <pre> + <code class="bash" data-trim data-line-numbers> + capturing + bubble + </code> + </pre> + </section> + <section> + <p>Aufgabe: Erweitere das vorherige Beispiel so, dass das div-Element einen weiteren Click-Handler bekommt, + der den Text "bubble2" anzeigt, nachdem "bubble" in der Konsole geloggt wurde.</p> + + <p>Erwartete Ausgabe:</p> + <pre> + <code class="bash" data-trim data-line-numbers> + capturing + bubble + bubble2 + </code> + </pre> + </section> + <section> + <p>Lösung:</p> + <pre> + <code class="js" data-trim data-line-numbers> + function doSomething(e) { + console.log("capture"); + } + + // neu + function doSomething2(e) { + console.log("bubble2"); + } + + function click(e) { + console.log("bubble"); + } + + div.addEventListener("click", doSomething, true); + div.addEventListener("click", doSomething2, false); // neu + + button.addEventListener("click", click, false /* default */); + </code> + </pre> + </section> + <section> + Die Bubble-Phase stoppen + <pre> + <code class="js" data-trim data-line-numbers> + function click(e) { + e.stopPropagation() + } + </code> + </pre> + </section> + <section> + <p>Aufgabe: Ändere das Ergebnis des vorherigen Beispiels, sodass die Bubble-Phase auf Ebene des button-Elements gestoppt wird. Was ändert sich in der Ausgabe?</p> + </section> + <section> + <p>Lösung:</p> + <pre> + <code class="js" data-trim data-line-numbers> + function doSomething(e) { + console.log("capture"); + } + + function doSomething2(e) { + console.log("bubble2"); + } + + function click(e) { + e.stopPropagation(); + console.log("bubble"); + } + + div.addEventListener("click", doSomething, true); + div.addEventListener("click", doSomething2, false); + + button.addEventListener("click", click, false /* default */); + </code> + </pre> + </section> + <section> + Events programatisch triggern: + <pre> + <code class="js" data-trim data-line-numbers> + button.dispatchEvent(new Event("click")); + </code> + </pre> + </section> + <section> + Events sind synchron: + <pre> + <code class="js" data-trim data-line-numbers> + doSomethingElse(); + + button.dispatchEvent(new Event("click")); + + doAnotherThing(); // wird erst ausgeführt, wenn zuvor alle Event-Handler fertig sind + </code> + </pre> + </section> </section> </div> </div> -- Gitblit v1.9.3