04 Recent Features

Recent Features: Overview

  • Spread Operator
  • Destructuring
  • Async Functions
  • String API
  • Optional Chaining
  • Nullish Coalescing

Spread Operator "..."

Array spreading


let array1 = [1,2,3];
let array2 = [4,5,6];

let result = [...array1, ...array2];

console.log(result); // [1,2,3,4,5,6]

Spread Operator "..."

Object spreading


let obj1 = {a:1, b:2, c:3};
let obj2 = {d:4, e:5, f:6};

let result = {...obj1, ...obj2};

console.log(result); // {a:1, b:2, c:3, d:4, e:5, f:6}

Spread Operator "..."

Core functionalities of a Prototype-based language:

  • Create
  • Merge
  • Shallow-copy (flat/deep)
  • Functions with variable arguments

Problems solved by "..."

  • lodash.js
  • Underscore.js
  • $.extend()
  • Object.extend()
  • Object.assign()
  • forEach(fnCopyProperties)
  • ...
no longer necessary ! => go native, remove unnecessary dependencies

Spread Operator "..."


                    {...obj1, ...obj2};
                    [...array1, ...array2];
                

Exercises [1-3, 4-5 optional]

Wrap-Up: Spread Operator

  • More intention revealing
  • Less verbose coding
  • No external dependencies

Destructuring

Object Destructuring


                    let { a, b, c } = { a:1, b:2, c:3 };

                    console.log(a); // 1
                    console.log(b); // 2
                    console.log(c); // 3
                

Live Demo

Destructuring

Object Destructuring


                    let [a,b,c] = [1,2,3];

                    console.log(a); // 1
                    console.log(b); // 2
                    console.log(c); // 3
                

Live Demo

Wrap-Up: Destructuring

  • Convenient shorthands
  • Less verbose coding
  • Trivial to use

Async Functions

async/await


                    async someAsyncCode() {
                        // save() is asynchronous (e.g Promise)
                        let animal = await db.save(createAnimal());
                        console.log("Sucessfully saved: " + animal);

                        // load() is asynchronous (e.g Promise)
                        let loaded = await db.load(animal.id);
                        console.log("Sucessfully loaded: " + loaded);
                    }
                

Problems solved by Async/Await

  • Busy-Wait & setTimeout() Loops
  • Nested Listeners
  • Nested Promises
  • Nested Observables
  • ...
no longer necessary ! => async/await

Async Functions


                    async functionName(someArgs) {
                        ...
                        let result = await someAsyncFunction(someArgs2);
                        ...
                    }
                

Exercises

Wrap-Up: Async Functions

  • Increased readability
  • Easier testing
  • Less coding

Common String-Problems

  • Padding
  • Trimming
  • Multi-Byte Strings
  • ...

Padding


                    function padLeft(num, size) {
                        var s = num+"";
                        while (s.length < size) s = "0" + s;
                        return s;
                    }

                    function padLeft(num, size) {
                        var s = "000000000" + num;
                        return s.substr(s.length - size);
                    }
                

by Stackoverflow et al.

Wtf! Noo !

Padding


                    "1".padStart(4, "0"); // 0001
                    "2".padEnd(4, "0"); // 2000

Check out the new String API !

Trimming


                    // trim right
                    " abc ".replace(/^\s+/g, ''); // "abc "

                    // trim left
                    " abc ".replace(/\s+$/g, ''); // " abc"

                    // trim both
                    " abc ".replace(/^\s+/g, '').replace(/\s+$/g, ''); // "abc"

by Stackoverflow et al.

Wtf! Noo !

Trimming

" abc ".trimLeft(); // "abc "
" abc ".trimRight(); // " abc"
" abc ".trim(); // "abc"

Check out the new String API !

Multi-byte Strings


                    // ⚠ ️Notice ...
                    let string = '❤️❤️❤heart'; // 👈🏼 emojis !
                    console.log(string == '\u2764\uFE0F\u2764\uFE0F\u2764heart');
                    console.log(string.length == 10); // true ;)
                    console.log('❤️' == '\u2764\uFE0F');

encoding gets slightly bit more complicated ;)

possibilities vs consequences

Optional Chaining

What Problem are we solving?

Reading the value of a property located deep within a chain of connected objects without having to expressly validate that each reference in the chain is valid

What is getting returned?

For all nullish values, undefined is returned.

Old Patterns


                    if (someObject) {
                        return someObject.someProperty;
                    }

                    if (someObject && someObject.someProperty) { ... }

                

New Pattern


                    return someObject?.someProperty;
                

Also works for Functions


                    someObject?.someFunction?.();
                

As with properties it will return undefined if the function wasn't found

Nullish Coalescing


                    let undefinedValue;

                    // current solution
                    const undefinedValue = undefinedValue || 'some default';
                    // unexpected results with falsy values like 0, false...

                    // with nullish coalescing
                    const nullValue = undefinedValue ?? 'some default';
                    // no other falsy values than "null" and "undefined" considered
                

Nullish Coalescing

  • Only works with "null" and "undefined"
  • More syntax to learn

Why bother about APIs ?

APIs are no Patterns !

Recent Features

  • ECMAScript is backed by Ecma TC39 committee
  • Problems are known and get addressed
  • Javascript is a really fast evolving language

Best practice

Check out the latest APIs - they probably changed since you read them the last time !

Can I use this?

Resources

Questions?