Sascha Schulz
2023-07-17 482a095e1eb9ffd81d6c34d376ce1562ccb73575
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>