Novinky v JavaScripte

vo verziách ES2015, ES2016, ES2017 a ES2018

ES2015

ES?

ECMAScript

ECMAScript

Oficiálny názov JavaScriptu

Java® je ochranná známka

ECMA

European Computer Manufacturers Association

ES2015 vs. ES6

  • Harmony
  • ES6
  • ES2015

Novinky ES2015

Literály pre binárne a oktálové čísla

var x = 0b1011;

var y = 0o715;

Deklarácia premenných

  • let

  • const

Dva nové spôsoby deklarácie

Blokový scope

let foo = 'foo';

foo = 'foo 2';

// ----

const bar = ['pivo'];

bar.push('vino');

bar = ['borovicka']; // TypeError: invalid assignment
                     // to const `bar`





Arrow funkcie

  • kratší zápis
  • uchovávanie kontextu (this, arguments)

Arrow funkcie - kratší zápis

var pow = function (arg) {
    return arg * arg;
};
const pow = (arg) => {
    return arg * arg;
};
const pow = (arg) => arg * arg;
// Pozor, zátvorky okolo argumentov sa dajú odobrať
// iba v prípade jednoargumentovej funkcie
// Funkcia bez argumentov musí mať zátvorky uvedené!
const getName = () => 'zelenina';
const pow = arg => arg * arg;

Arrow funkcie - zdieľanie kontextu

const tyrion = {
    name: 'tyrion',
    tags: ['piť', 'nadávať', 'veci'],

    printKnowledge: function () {
        this.tags.forEach(function (tag) {
            console.log(this.name + ' vie ' + tag);
        });
    }
};

tyrion.printKnowledge();

Skúste tento kód opraviť v starom JS (bez arrow funkcie)

Arrow funkcie - zdieľanie kontextu

const tyrion = {
    name: 'tyrion',
    tags: ['piť', 'nadávať', 'veci'],

    printKnowledge: function () {
        const that = this;

        this.tags.forEach(function (tag) {
            console.log(that.name + ' vie ' + tag);
        });
    }
};

tyrion.printKnowledge();

Starý JS: pomocná premenná "that"

Arrow funkcie - zdieľanie kontextu

const tyrion = {
    name: 'tyrion',
    tags: ['piť', 'nadávať', 'veci'],

    printKnowledge: function () {
        this.tags.forEach((function (tag) {
            console.log(this.name + ' vie ' + tag);
        }).bind(this));
    }
};

tyrion.printKnowledge();

Starý JS: bindovanie

Arrow funkcie - zdieľanie kontextu

const tyrion = {
    name: 'tyrion',
    tags: ['piť', 'nadávať', 'veci'],

    printKnowledge: function () {
        this.tags.forEach((tag) => {
            console.log(this.name + ' vie ' + tag);
        });
    }
};

tyrion.printKnowledge();

Nový JS: array funkcia

Rozšírené objektové literály

const name = 'Ferko';
const lastName = 'Mrkvička';
const x = 'abc';
const y = 'def';

const fero = {};

/* Pre objekt fero:
 * - vytvorte property name a lastName,
 *   ktoré budú mať hodnoty z premenných vyššie
 * - vytvorte metódu foo, ktorá vráti reťazec 'metóda foo'
 * - vytvorte property, ktorej názov je poskladaný z x a y.
 */

console.log(fero.name);
console.log(fero.lastName);
console.log(fero.foo());
console.log(fero.abcdef);

Rozšírené objektové literály

const name = 'Ferko';
const lastName = 'Mrkvička';
const x = 'abc';
const y = 'def';

const fero = {
    name: name,
    lastName: lastName,
    
    // vytvorte metódu foo, ktorá vráti reťazec 'metóda foo'
    // vytvorte property, ktorej názov je poskladaný z x a y.
};

console.log(fero.name);
console.log(fero.lastName);
console.log(fero.foo());
console.log(fero.abcdef);

V starom JS

Rozšírené objektové literály

const name = 'Ferko';
const lastName = 'Mrkvička';
const x = 'abc';
const y = 'def';

const fero = {
    name: name,
    lastName: lastName,
    
    foo: function () {
        return 'metóda foo';
    },
  
    // vytvorte property, ktorej názov je poskladaný z x a y.
};

console.log(fero.name);
console.log(fero.lastName);
console.log(fero.foo());
console.log(fero.abcdef);

V starom JS

Rozšírené objektové literály

const name = 'Ferko';
const lastName = 'Mrkvička';
const x = 'abc';
const y = 'def';

const fero = {
    name: name,
    lastName: lastName,
    
    foo: function () {
        return 'metóda foo';
    },
};

fero[x + y] =  'počítaná property';

console.log(fero.name);
console.log(fero.lastName);
console.log(fero.foo());
console.log(fero.abcdef);

V starom JS

Rozšírené objektové literály

const name = 'Ferko';
const lastName = 'Mrkvička';
const x = 'abc';
const y = 'def';

const fero = {
    name,
    lastName,
    
    foo() {
        return 'metóda foo';
    },
    
    [x + y]: 'počítaná property',
};

console.log(fero.name);
console.log(fero.lastName);
console.log(fero.foo());
console.log(fero.abcdef);

V novom JS

const name = 'Ferko';
const lastName = 'Mrkvička';
const x = 'abc';
const y = 'def';

const fero = {
    name,
    lastName,
    
    foo() {
        return 'metóda foo';
    },
    
    [x + y]: 'počítaná property',
};

console.log(fero.name);
console.log(fero.lastName);
console.log(fero.foo());
console.log(fero.abcdef);
const name = 'Ferko';
const lastName = 'Mrkvička';
const x = 'abc';
const y = 'def';

const fero = {
    name: name,
    lastName: lastName,
    
    foo: function () {
        return 'metóda foo';
    },
};

fero[x + y] =  'počítaná property';

console.log(fero.name);
console.log(fero.lastName);
console.log(fero.foo());
console.log(fero.abcdef);

Destructuring - polia

const [x, y] = [1, 2];

const pole = ['agát', 'blýskavica', 'cieľovníci'];

const [a, , c] = pole;

const [foo, bar, baz = 33] = [11, 22];

// výmena hodnôt dvoch prvkov

let [var1, var2] = ['value 1', 'value 2'];

[var2, var1] = [var1, var2];

Destructuring - objekty

const obj = {
    foo: 1,
    bar: 2,
    baz: 3,
};

const { foo, baz } = obj;

// prípadne pod iným názvom
const { foo: aliasFoo, baz } = obj;

// default hodnoty

const { foo, xyz = 42 } = obj;

Destructuring - objekty

// argumenty funkcie

const params = {
    logger: 'console',
    isDev:  true,
};

foo(params);

const foo = function ({ isDev, logger }) {
    console.log(logger);
    console.log(isDev);
};

Default hodnoty argumentov funkcie

const foo = function (x, y = 5) {
    // ...
};

const bar = (x, y = 5) => {
    // ...
};

Rest operátor

const foo = (x, ...y) => {
    console.log(y);
};

foo(1, 2, 3, 4, 5);

Spread operátor

const foo = (x, y, z) => {
    console.log(x, y, z);
};

const arr = [1, 2, 3];

foo(...arr);
const foo = (x, y, ...z) => {
    console.log(z);
};

const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const arr3 = [7, 8, 9];

// čo bude vypísané v konzole?
foo(...arr1, ...arr2, ...arr3);







Chvíľka na zamyslenie

const foo = (x, y, ...z) => {
    console.log(z);
};

const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const arr3 = [7, 8, 9];

// čo bude vypísané v konzole?
foo(...arr1, ...arr2, ...arr3);
// [3, 4, 5, 6, 7, 8, 9]






Chvíľka na zamyslenie

const foo = (x, y, ...z) => {
    console.log(z);
};

const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const arr3 = [7, 8, 9];

// čo bude vypísané v konzole?
foo(...arr1, ...arr2, ...arr3);
// [3, 4, 5, 6, 7, 8, 9]

foo(arr1, arr2, ...arr3);




Chvíľka na zamyslenie

const foo = (x, y, ...z) => {
    console.log(z);
};

const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const arr3 = [7, 8, 9];

// čo bude vypísané v konzole?
foo(...arr1, ...arr2, ...arr3);
// [3, 4, 5, 6, 7, 8, 9]

foo(arr1, arr2, ...arr3);
// [7, 8, 9]



Chvíľka na zamyslenie

const foo = (x, y, ...z) => {
    console.log(z);
};

const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const arr3 = [7, 8, 9];

// čo bude vypísané v konzole?
foo(...arr1, ...arr2, ...arr3);
// [3, 4, 5, 6, 7, 8, 9]

foo(arr1, arr2, ...arr3);
// [7, 8, 9]

foo(...arr1, arr2, ...arr3);

Chvíľka na zamyslenie

const foo = (x, y, ...z) => {
    console.log(z);
};

const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const arr3 = [7, 8, 9];

// čo bude vypísané v konzole?
foo(...arr1, ...arr2, ...arr3);
// [3, 4, 5, 6, 7, 8, 9]

foo(arr1, arr2, ...arr3);
// [7, 8, 9]

foo(...arr1, arr2, ...arr3);
// [3, [4, 5, 6], 7, 8, 9]

Chvíľka na zamyslenie

Template string

const multiline = `toto je viacriadkový
reťazec
`;

console.log(multiline);

const str = 'reťazec';
const val = 'hodnotami';

const replaced = `toto je ${str} s nahradenými ${val}`;

console.log(replaced);

Generátory

const gen = function* () {
    let n = 1;

    while (true) {
        yield n;
        n++;
    }
}

const generator = gen();

console.log(generator.next());

for-of cyklus

const arr = [1, 2, 3, 4, 5];

for (const i of arr) {
    console.log(i);
}
const foo = function* () {
    yield 1;
    yield 2;
}

for (const i of foo()) {
    console.log(i);
}
const str = 'hello world';

for (const c of str) {
    console.log(c);
}

Iterátory

const cart = {
    price: 23.5,
    items: ['jablko', 'hruska', 'banan'],

    [Symbol.iterator]: function* () {
        let i = 0;

        while (i < this.items.length) {
            yield this.items[i];
            i++;
        }
    }
};

for (const i of cart) {
    console.log(i);
}

Unicode

Plná podpora Unicode v reťazcoch a regulárnych výrazoch

Rozšírenia pre Number

Number.EPSILON

Number.isInteger(Infinity)

Number.isNaN(NaN)

String.prototype.includes, String.prototype.repeat

"ferko mrkvička".includes("mrk");

"abc".repeat(3);

Object.assign

let person = {id: 42};

person = Object.assign(
    person,
    {
        name: 'fero',
    },
    {
        name: 'jozo',
        surname: 'mrkvicka',
    },
    {
        name: 'ferko',
    }
);

Rozšírenia pre Array

Array.from('hello'); // ['h', 'e', 'l', 'l', 'o']

Array.from([1, 2, 3]); // [1, 2, 3]

Array.from([1, 2, 3], x => x + 10); // [11, 12, 13]

Array.from({ length: 5 }, (v, i) => i); // [0, 1, 2, 3, 4]

// -----

Array.of(1, 2, 3); // [1, 2, 3]

Rozšírenia pre Array.prototype

const arr = [0, 0, 0, 0]

arr.fill(7, 1, 2);

console.log(arr); // [0, 7, 0, 0]

// ---

const idx = arr.findIndex(x => x == 7);

console.log(idx); // 1

Rozšírenia pre Array.prototype

const arr = ['a', 'b', 'c'];

for (const i of arr.entries()) {
    console.log(i);
}

for (const i of arr.keys()) {
    console.log(i);
}

for (const i of arr.values()) {
    console.log(i);
}

Nové metódy entries, keys a values, ktoré vracajú iterátor.

Ďalšie novinky:

  • Promise
  • Triedy
  • Moduly

ES2016

const pole = [1, 2, 3];

pole.includes(5);










Zisťuje, či v poli existuje hodnota

Array.prototype.includes

const pole = [1, 2, 3];

pole.includes(5);  // false










Zisťuje, či v poli existuje hodnota

Array.prototype.includes

const pole = [1, 2, 3];

pole.includes(5);  // false

pole.includes(2);








Zisťuje, či v poli existuje hodnota

Array.prototype.includes

const pole = [1, 2, 3];

pole.includes(5);  // false

pole.includes(2);  // true








Zisťuje, či v poli existuje hodnota

Array.prototype.includes

const pole = [1, 2, 3];

pole.includes(5);  // false

pole.includes(2);  // true

pole.includes('2');






Zisťuje, či v poli existuje hodnota

Array.prototype.includes

const pole = [1, 2, 3];

pole.includes(5);  // false

pole.includes(2);  // true

pole.includes('2');  // false






Zisťuje, či v poli existuje hodnota

Array.prototype.includes

const pole = [1, 2, 3];

pole.includes(5);  // false

pole.includes(2);  // true

pole.includes('2');  // false

pole.includes(undefined);




Zisťuje, či v poli existuje hodnota

Array.prototype.includes

const pole = [1, 2, 3];

pole.includes(5);  // false

pole.includes(2);  // true

pole.includes('2');  // false

pole.includes(undefined); // false




Zisťuje, či v poli existuje hodnota

Array.prototype.includes

const pole = [1, 2, 3];

pole.includes(5);  // false

pole.includes(2);  // true

pole.includes('2');  // false

pole.includes(undefined); // false

delete pole[1];

pole.includes(undefined);

Zisťuje, či v poli existuje hodnota

Array.prototype.includes

Array.prototype.includes

const pole = [1, 2, 3];

pole.includes(5);  // false

pole.includes(2);  // true

pole.includes('2');  // false

pole.includes(undefined); // false

delete pole[1];

pole.includes(undefined); // true

Zisťuje, či v poli existuje hodnota

Umocňovací operátor **

console.log(
    4 ** 2,
);

// 16

Výsledok je totožný s Math.pow(), ale funguje aj pre BigInt (ES2020)

ES2017

Zarovnávanie stringov

'ahoj'.padStart(4);




















Nové metódy padStart() a padEnd()

Zarovnávanie stringov

'ahoj'.padStart(4);
// 'ahoj'



















Nové metódy padStart() a padEnd()

Zarovnávanie stringov

'ahoj'.padStart(4);
// 'ahoj'
'ahoj'.padStart(5);


















Nové metódy padStart() a padEnd()

Zarovnávanie stringov

'ahoj'.padStart(4);
// 'ahoj'
'ahoj'.padStart(5);
// ' ahoj'

















Nové metódy padStart() a padEnd()

Zarovnávanie stringov

'ahoj'.padStart(4);
// 'ahoj'
'ahoj'.padStart(5);
// ' ahoj'
'ahoj'.padStart(7);
















Nové metódy padStart() a padEnd()

Zarovnávanie stringov

'ahoj'.padStart(4);
// 'ahoj'
'ahoj'.padStart(5);
// ' ahoj'
'ahoj'.padStart(7);
// '   ahoj'















Nové metódy padStart() a padEnd()

Zarovnávanie stringov

'ahoj'.padStart(4);
// 'ahoj'
'ahoj'.padStart(5);
// ' ahoj'
'ahoj'.padStart(7);
// '   ahoj'
'ahoj'.padStart(7, 'abcdefghi');














Nové metódy padStart() a padEnd()

Zarovnávanie stringov

'ahoj'.padStart(4);
// 'ahoj'
'ahoj'.padStart(5);
// ' ahoj'
'ahoj'.padStart(7);
// '   ahoj'
'ahoj'.padStart(7, 'abcdefghi');
// 'abcahoj'













Nové metódy padStart() a padEnd()

Zarovnávanie stringov

'ahoj'.padStart(4);
// 'ahoj'
'ahoj'.padStart(5);
// ' ahoj'
'ahoj'.padStart(7);
// '   ahoj'
'ahoj'.padStart(7, 'abcdefghi');
// 'abcahoj'
'7'.padStart(3, '0');












Nové metódy padStart() a padEnd()

Zarovnávanie stringov

'ahoj'.padStart(4);
// 'ahoj'
'ahoj'.padStart(5);
// ' ahoj'
'ahoj'.padStart(7);
// '   ahoj'
'ahoj'.padStart(7, 'abcdefghi');
// 'abcahoj'
'7'.padStart(3, '0');
// '007'











Nové metódy padStart() a padEnd()

Zarovnávanie stringov

'ahoj'.padStart(4);
// 'ahoj'
'ahoj'.padStart(5);
// ' ahoj'
'ahoj'.padStart(7);
// '   ahoj'
'ahoj'.padStart(7, 'abcdefghi');
// 'abcahoj'
'7'.padStart(3, '0');
// '007'

'ahoj'.padEnd(4);









Nové metódy padStart() a padEnd()

Zarovnávanie stringov

'ahoj'.padStart(4);
// 'ahoj'
'ahoj'.padStart(5);
// ' ahoj'
'ahoj'.padStart(7);
// '   ahoj'
'ahoj'.padStart(7, 'abcdefghi');
// 'abcahoj'
'7'.padStart(3, '0');
// '007'

'ahoj'.padEnd(4);
// 'ahoj'








Nové metódy padStart() a padEnd()

Zarovnávanie stringov

'ahoj'.padStart(4);
// 'ahoj'
'ahoj'.padStart(5);
// ' ahoj'
'ahoj'.padStart(7);
// '   ahoj'
'ahoj'.padStart(7, 'abcdefghi');
// 'abcahoj'
'7'.padStart(3, '0');
// '007'

'ahoj'.padEnd(4);
// 'ahoj'
'ahoj'.padEnd(3);







Nové metódy padStart() a padEnd()

Zarovnávanie stringov

'ahoj'.padStart(4);
// 'ahoj'
'ahoj'.padStart(5);
// ' ahoj'
'ahoj'.padStart(7);
// '   ahoj'
'ahoj'.padStart(7, 'abcdefghi');
// 'abcahoj'
'7'.padStart(3, '0');
// '007'

'ahoj'.padEnd(4);
// 'ahoj'
'ahoj'.padEnd(3);
// 'ahoj'






Nové metódy padStart() a padEnd()

Zarovnávanie stringov

'ahoj'.padStart(4);
// 'ahoj'
'ahoj'.padStart(5);
// ' ahoj'
'ahoj'.padStart(7);
// '   ahoj'
'ahoj'.padStart(7, 'abcdefghi');
// 'abcahoj'
'7'.padStart(3, '0');
// '007'

'ahoj'.padEnd(4);
// 'ahoj'
'ahoj'.padEnd(3);
// 'ahoj'
'ahoj'.padEnd(7);





Nové metódy padStart() a padEnd()

Zarovnávanie stringov

'ahoj'.padStart(4);
// 'ahoj'
'ahoj'.padStart(5);
// ' ahoj'
'ahoj'.padStart(7);
// '   ahoj'
'ahoj'.padStart(7, 'abcdefghi');
// 'abcahoj'
'7'.padStart(3, '0');
// '007'

'ahoj'.padEnd(4);
// 'ahoj'
'ahoj'.padEnd(3);
// 'ahoj'
'ahoj'.padEnd(7);
// 'ahoj   '




Nové metódy padStart() a padEnd()

Zarovnávanie stringov

'ahoj'.padStart(4);
// 'ahoj'
'ahoj'.padStart(5);
// ' ahoj'
'ahoj'.padStart(7);
// '   ahoj'
'ahoj'.padStart(7, 'abcdefghi');
// 'abcahoj'
'7'.padStart(3, '0');
// '007'

'ahoj'.padEnd(4);
// 'ahoj'
'ahoj'.padEnd(3);
// 'ahoj'
'ahoj'.padEnd(7);
// 'ahoj   '
'ahoj'.padEnd(7, 'abcdefghi');



Nové metódy padStart() a padEnd()

Zarovnávanie stringov

'ahoj'.padStart(4);
// 'ahoj'
'ahoj'.padStart(5);
// ' ahoj'
'ahoj'.padStart(7);
// '   ahoj'
'ahoj'.padStart(7, 'abcdefghi');
// 'abcahoj'
'7'.padStart(3, '0');
// '007'

'ahoj'.padEnd(4);
// 'ahoj'
'ahoj'.padEnd(3);
// 'ahoj'
'ahoj'.padEnd(7);
// 'ahoj   '
'ahoj'.padEnd(7, 'abcdefghi');
// 'ahojabc'


Nové metódy padStart() a padEnd()

Zarovnávanie stringov

'ahoj'.padStart(4);
// 'ahoj'
'ahoj'.padStart(5);
// ' ahoj'
'ahoj'.padStart(7);
// '   ahoj'
'ahoj'.padStart(7, 'abcdefghi');
// 'abcahoj'
'7'.padStart(3, '0');
// '007'

'ahoj'.padEnd(4);
// 'ahoj'
'ahoj'.padEnd(3);
// 'ahoj'
'ahoj'.padEnd(7);
// 'ahoj   '
'ahoj'.padEnd(7, 'abcdefghi');
// 'ahojabc'
'7'.padEnd(3, '0');

Nové metódy padStart() a padEnd()

Zarovnávanie stringov

'ahoj'.padStart(4);
// 'ahoj'
'ahoj'.padStart(5);
// ' ahoj'
'ahoj'.padStart(7);
// '   ahoj'
'ahoj'.padStart(7, 'abcdefghi');
// 'abcahoj'
'7'.padStart(3, '0');
// '007'

'ahoj'.padEnd(4);
// 'ahoj'
'ahoj'.padEnd(3);
// 'ahoj'
'ahoj'.padEnd(7);
// 'ahoj   '
'ahoj'.padEnd(7, 'abcdefghi');
// 'ahojabc'
'7'.padEnd(3, '0');
// '700'

Nové metódy padStart() a padEnd()

Object.values()

const osoba = {
    meno: 'fero',
    vek: 23,
};

Object.values(osoba);

// ['fero', 23]

Vráti pole obsahujúce vlastné property objektu

Object.entries()

const osoba = {
    meno: 'fero',
    vek: 23,
};

Object.entries(osoba);

// [['meno', 'fero'], ['vek', 23]]

Vráti pole obsahujúce polia kľúčov a hodnôt vlastných properties

Object.getOwnPropertyDescriptors()

Vráti objekt so všetkými descriptormi všetkých vlastných properties objektu

Descriptory sú sadou informácií o property, ktoré ju plne definujú.

  • value: hodnota
  • writable: vieme zapisovať?
  • get: getter funkcia, ktorá sa volá pri čítaní
  • set: setter funkcia, ktorá sa volá pri zápise
  • configurable: ak je false, tak nevieme zmeniť nič okrem value
  • enumerable: je vymenovateľná?

Object.getOwnPropertyDescriptors()

const osoba = {
    meno: 'fero',
    vek: 23,
};

Object.getOwnPropertyDescriptors(osoba);

Vráti objekt so všetkými descriptormi všetkých vlastných properties objektu

K čomu to je?

Object.assign ignoruje non-enumerable property.

Pomocou tejto metódy a Object.defineProperties() to vieme obísť

Trailing commas

function foo(
    abc,
    def,
    ghi,
) {
    // ...  
}

foo(
    123,
    456,
    789,
);

Môžeme mať nadbytočné čiarky v definícii aj volaní funkcie

Asynchrónne funkcie

function foo() {
    return new Promise((resolve) => {
        setTimeout(
            () => resolve('fooooo'),
            3000
        )
    });
}

function bar() {
    console.log('pred foo');
    foo().then((value) => {
        console.log('po foo', value);  
    });
}

async / await

Doplnok k promisom a generátorom

Asynchrónne funkcie

function foo() {
    return new Promise((resolve) => {
        setTimeout(
            () => resolve('fooooo'),
            3000
        )
    });
}

async function bar() {
    console.log('pred foo');
    const value = await foo();
    console.log('po foo', value);
}

async / await

Doplnok k promisom a generátorom

Asynchrónne funkcie

async / await

  • doplnok k promisom a generátorom
  • nemáme callback hell, čo poriešili Promises
  • a nemáme ani promise-syntax hell
  • pozor: await vieme použiť iba vo vnútri async funkcie

Zdieľaná pamäť medzi webworkerom a jeho tvorcom

SharedArrayBuffer

ES2018

Rest/Spread pre objekty

const person = {
    name: 'Ferko',
    surname: 'Mrkvička',
    email: 'ferko.mrkvicka@example.com',
    phone: '+111222333444'
};

//rest
const { name, surname, ...others} = person;

// spread
const personWithAge = {
    ...person,
    age: 23,
}

for-await-of

async function* getData() {
    yield 'mrkva';
    yield 'jablko';
    yield 'pomaranc';
}

// ...
for await (const i of getData()) {
    // do something
}

Môžeme iterovať nad asynchrónnym iterovateľným "objektom"

Promise.prototype.finally

fetch()
    .then(() => { /* ... */ })
    .then(() => { /* ... */ })
    .catch(() => { /* ... */ })
    .finally(() => { /* ... */ })

Promisy dostali metódu finally, ktorá sa vykoná bez ohľadu na to, či došlo alebo nedošlo k chybe.

Vylepšenia pre RegExp

  • look-behind ?<=, ?<!
  • pomenované capturing groupy ?<meno>
  • nový flag s pre single line porovnávanie (do bodky sa zahrnie aj znak nového riadku)

Ďakujem za pozornosť