Session III

Session III: Advanced Javascript, ES6 and beyond, jquery

17. Nov. 2021, 14:00-17:00

Artful Coding 1: web-based games development

dieAngewandte

Contents

  • ECMAScript and what's new with ES6 and later?
  • Loops
  • Function declarations
  • Objects and classes
  • Interim exercise & break
  • Scope and Closures
  • Maps and Sets
  • Regular expressions
  • Callbacks and Promises
  • jQuery
  • Open questions & break & exercise

ECMA Script

"The ECMAScript specification is a standardised specification of a scripting language developed by Brendan Eich of Netscape; initially named Mocha, then LiveScript, and finally JavaScript." (Wikipedia: ECMAScript)

Loops (the old way)


            var i = 0;
            while (i < 100) {
              // doing some stuff here
              console.log(i)

              // increasing the loop condition
              i++
            }
          

or: with for


              for (var i=0; i<100; i++) {
                // doing some stuff here
                console.log(i)
              }
            

Loops (the ES5 way)


            function addRhythmCounter(number) {
              console.log(number);
              rhythm += number + ", and ";
            }

            const numbers = [1, 2, 1, 2, 3, 4];
            let rhythm = "and counting ";
            numbers.forEach(addRhythmCounter);
            console.log(rhythm);
          

Looping through object properties

And only object properties! Do not use this on arrays!


            let someOne = {
              firstname: "Jane",
              lastname: "Doe",
              age: 42,
            }

            for (const property in someOne) {
              console.log(property, someOne[property])
            }
          

Loops (the ES6 way)


            let iterable = ["A", "random", "assortment", "of", 6, "things"];
            for (const item of iterable) {
              console.log(item)
            }
            iterable = "A random assortment of many more things";
            for (const item of iterable) {
              console.log(item)
            }
          

functions

is there anything they can't do?

Everything you need to know about functions:
JavaScript Function Definitions @ w3schools

objects

is there anything that isn't one?

The most important thing you need to know about objects:
JavaScript Objects @ w3schools


            // practical if you want to bundle properties and methods
            const player = {
              name: "Balthazaaar",
              type: "dirt-devil",
              health: 100,
              xp: 0,
              quests: [],
              acceptQuest: function (questID) {
                this.quests.push(questID)
                // do something
              }
            }
          

classes

a factory for making objects

All the fuzz about class:
JavaScript Class Syntax @ w3schools


            // practical e.g. if we do not just only want ONE player, but many characters
            class Character {
              constructor (name, type) {
                this.name = name
                this.type = type
                this.health = 100
                this.xp = 0
                this.quests = []

                if (type == 'wonderwuzz') {
                  this.xp = 1000
                }
              }

              acceptQuest (questID) {
                this.quests.push(questID)
                // do something interesting
              }
            }

            const playerB = new Character('Balthazaaar', 'dirt-devil')
            const playerA = new Character('Ada', 'wonderwuzz')

            playerA.acceptQuest(23)
            playerB.acceptQuest(42)
            playerB.acceptQuest(5)

            console.log(playerA)
            console.log(playerB)
          

Interim exercise

Create:

  • a function that contains a loop with a counter from 1 to 100. In every loop iteration the current loop counter should be printed to the console.
  • a plain HTML page with a button called "debug", which calls the function, when the user clicks on the button.

Scope

3 types of scope in JS, which determine the visibility/accessibility of variables

  • global scope
  • function scope
  • block scope (since ES6)

scope with var


            var x = 23;  // global scope

            function doSomething () {
              // a function always has access to parent scope
              console.log('doing something with x:', x);  // 23
            }

            function doSomeMore () {
              var x = 'WTF?!?';  // function scope masks the parent/global scope
              var y = 42;        // function scope
              console.log('x inside something:', x);  // 'WTF?!?'
              console.log('y inside something:', y);  // 42
            }

            doSomething();
            doSomeMore();

            console.log('x in global scope:', x);  // 23
            console.log('y in global scope:', y);  // throws error, existed only in doSomeMore()

            if ( true ) {
              var x = 'block23';  // no block scope available with var -> global scope
              var z = 'mimimi';   // no block scope available with var -> global scope
            }
            console.log('x after assignment in block:', x);  // 'block23'
            console.log('z outside of scoped block:', z);    // 'mimimi'
          

block scope and let


            let x = 23;  // global scope

            // doSomething() and doSomeMore() work similar with let than in the var example
            // only let does not let you redeclare a variable if it was already
            // declared once, in the scope (var would let you do that)

            // but now for the block scope thingy
            if ( true ) {
              let x = 'block23';  // block scope
              let z = 'mimimi';   // block scope
            }
            console.log('x after assignment in block:', x);  // 23, the 'block23'-x only existed in block
            console.log('z outside of scoped block:', z);    // throws error, existed only in block
          

Closures

The problem


            // Initiate counter
            let counter = 0;

            // Function to increment counter
            function add() {
              counter += 1;
            }

            // Call add() 3 times
            add();
            add();
            add();

            // The counter should now be 3
            // But: everything with access to the global scope can change the counter
          

Closures

The solution


            const add = (function () {
             let counter = 0;
             return function () {counter += 1; return counter}
            })();

            add();
            add();
            add();

            // the counter is now 3
            // And: only the add() function has access to the counter variable
          

Sets

A set is a collection of unique values.


            const emptySet = new Set();
            emptySet.add(1);  // now contains: 1
            emptySet.add(2);  // now contains: 1, 2
            emptySet.add(2);  // now contains: 1, 2
            console.log(emptySet);  // Set { 1, 2 }

            const letters = new Set(["a","b","c","c","c"]);
            letters.add("d");     // now contains: a, b, c, d
            letters.delete("a");  // now contains: b, c, d
            console.log(letters.has("b"))  // true
            console.log(letters);  // Set { 'b', 'c', 'd' }

            for (const letter of letters.values()) {
              console.log(letter);
            }
          

Maps

A map is a set of key-value pairs


            const myMap = new Map();
            myMap.set("number", 42);
            myMap.set("name", "John");
            myMap.set("name", "Jane");
            myMap.set("Name", "Doe");
            myMap.set(42, "the answer");
            myMap.set(true, false);

            console.log(myMap.get("number"))  // 42
            console.log(myMap.get(42))        // the answer
            console.log(myMap.get(true))      // false
            console.log(myMap.get(false))     // undefined
            myMap.delete(true)

            for (const [key, value] of myMap.entries()) {
              console.log(key, value)
            }
          

Regular expressions

Powerfull text search and replace patterns:
Regular Expressions @ MDN dev docs


            // outline of a regex: /pattern/flags
            const re1 = /some\w*/ig
            const re2 = new RegExp('some\\w*', 'ig')

            let matches = 'Someone is doing something'.matchAll(re1)
            for (const match of matches) {
              console.log(match)
            }
          

Callbacks

Functions which are passed as parameters to other functions

so they can be called later


            // e.g. for events
            const doSomething = function () { alert('something!') }
            document.getElementById('myButton').onclick = doSomething

            // or timers
            let timeoutID = setTimeout(() => {console.log("time's up!")}, 5000)

            // or intervals
            let counter = 0
            function count () {
              counter++
              console.log(counter)
            }
            const counterInterval = setInterval(count, 1000)
          

Promises

... promise to keep you out of the callback pyramid of doom:
Using Promises

@ MDN dev docs

            doSomething().then(doSomethingElse, displayError)

            doSomething()
              .then(result => doSomethingElse(result))
              .then(newResult => doThirdThing(newResult))
              .then(finalResult => {
                console.log(`Got the final result: ${finalResult}`);
              })
              .catch(failureCallback);
          

jQuery

"jQuery is a fast, small, and feature-rich JavaScript library. It makes things like HTML document traversal and manipulation, event handling, animation, and Ajax much simpler with an easy-to-use API that works across a multitude of browsers." (jquery.com)


            $( 'p.quest-details' ).show()
            $( 'p.quest-details' ).hide( 'slow' )
            $( 'p.quest-details' ).toggle()

            const $history = $( '#player-history' )
            let $newHistItem = $( '
  • Something strange happened!
  • ' ) $history.append( $newHistItem )

    Including jQuery

    Either load it through a CDN like code.jquery.com or go to jquery.com/download, and put the version you want to use into your project assets.

    
                <!-- through a CDN: -->
                <script
                  src="https://code.jquery.com/jquery-3.6.0.min.js"
                  integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
                  crossorigin="anonymous"></script>
    
                <!-- as a project asset -->
                <script src="assets/jquery-3.6.0.min.js">
              

    jQuery : document ready?

    
                $( document ).ready(function() {
                  // initialise app
                });
    
                // $() is a shorthand for $(document).ready()
                // if you want to be nice use the upper version
                $(() => {
                  // initialise app
                })
              

    More on app initialisation with jQuery: $( document ).ready()

    jQuery example page

    loaded through CDN
    loaded as asset

    🤔   Questions?   🤔

    💬   Discussion?   💬

    next up:
    short break and exercise co-working