ES2015 a ešte ďalej

02/2017 / Milan "perún" Herda / @moriquend / prezentacie.perunhq.org

Čo je ES2015?

Štandard definujúci JavaScript, ktorý priniesol mnohé zásadné zmeny.

Prečo ten názov?

  • ES je skratkou od ECMAScript
  • ECMAScript je oficiálny názov JavaScriptu
  • Oficiálny názov nie je JavaScript, lebo Sun/Oracle má ochrannú známku na názov Java
  • ECMA je European Computer Manufacturers Association sídliaca v Ženeve

Prečo 2015?

  • Predchádzajúca verzia bola ES5.1 (jún 2011), resp. ES5 (december 2009)
  • Nový štandard sa vyvíjal pod názvom Harmony
  • Dlho sa myslelo, že nový názov bude ES6
  • Bolo zrušené verzionovanie a vznikla idea One JavaScript
  • Schváľovalo sa v roku 2015 a dohodlo sa, že každý rok bude inkrementálny upgrade (ES2016, ES2017)

Aké sú novinky?

Veľké a veľa

Ide o najväčší upgrade jazyka od jeho vzniku.

Deklarácia premenných

Pridané dva nové spôsoby deklarácie premenných.

Oba vytvárajú premenné s blokovým scopom.

  • let - dá sa meniť
  • const - nedá sa meniť (konštanta)
  • var - dá sa meniť, starý spôsob, funkčná platnosť

let foo = 'foo';

const bar = 'bar';

var baz = 'baz';
                    

Arrow funkcie

  • kratší zápis
  • uchovávanie kontextu (neprepisuje this, zdieľa arguments)

Arrow funkcie - kratší zápis


const sum = (param1, param2) => {
    return param1 + param2;
};

const pow = (param) => {
    return param * param;
}

const pow2 = param => param * param;
// ^ takto sa dajú skrátiť iba jednopríkazové
                    

Arrow funkcie - zdieľanie kontextu


const fero = {
    name: 'fero',
    tags: [ 'php', 'js', 'perl'],

    printKnowledge: function () {
        this.tags.map(function (tag) {
            console.log(this.name + ' pozná ' + tag);
            //          ^ TypeError: Cannot read property 'name' of undefined
        });
    },
};
                        

Arrow funkcie - zdieľanie kontextu

Obídenie problému


const fero = {
    name: 'fero',
    tags: [ 'php', 'js', 'perl'],

    printKnowledge: function () {
        const that = this;

        this.tags.map(function (tag) {
            console.log(that.name + ' pozná ' + tag);
        });
    },
};
                        

Arrow funkcie - zdieľanie kontextu

Riešenie cez arrow funkciu


const fero = {
    name: 'fero',
    tags: [ 'php', 'js', 'perl'],

    printKnowledge: function () {
        this.tags.map(tag => {
            console.log(this.name + ' pozná ' + tag);
        });
    },
};
                        

Export/import modulov

O tomto sme mali samostatný workshop

Rozšírené objektové literály


const name = 'fero';
const lastName = 'mrkvicka';

const fero = {
    name,
    lastName,
    foo() {
        // do something
    },
    ['abc' + 'foo']: 'počítané property',
};

const fero = {
    name: name,
    lastName: lastName,
    foo: function () {
        // do something
    },
    'abcfoo': 'počítané property',
};
                    

Destructuring


// polia
const [a, b] = [1, 2];
const [a, , c] = [1, 2, 3];

// objekty
const {foo, baz} = {foo: 1, bar: 2, baz: 3};
const {foo: alias, baz} = {foo: 1, bar: 2, baz: 3};

// default hodnoty
const [a, b, c = 3] = [1, 2];
const {foo, bar = 123} = {foo: 42};

// argumenty funkcie
const f = function ({foo, bar}) { /* ... */ };

f({
    foo: 'foo',
    bar: 'bar',
});
                    

Default hodnoty parametrov


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

Rest operátor


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

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

Spread operátor


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

const arr = [1, 2, 3];

foo(...arr);
                    

Template string


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

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

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

for-of cyklus


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

for (const n of arr) {
    console.log(n);
}
                    
* Ak transpilujete cez babel, tak potrebujete import 'babel-polyfill';

Generátory


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

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

const generator = gen();

console.log(generator.next());
// {value: 1, done: false}
                    
* Ak transpilujete cez babel, tak potrebujete import 'babel-polyfill';

Iterátory


const counter = {
    [Symbol.iterator]: function* () {
        let n = 1;

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

for (const i of counter) {
    console.log(i);

    if (i >= 10) {
        break;
    }
}
                    
* Ak transpilujete cez babel, tak potrebujete import 'babel-polyfill';

Unicode

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

Rozšírenia pre Number


Number.EPSILON
Number.isInteger(Infinity) // false
Number.isNaN("NaN")        // false
                    
* Ak transpilujete cez babel, tak potrebujete import 'babel-polyfill';

Rozšírenia pre String


"ferko mrkvicka".includes("mrk") // true
"abc".repeat(4)                  // "abcabcabcabc"
                    
* Ak transpilujete cez babel, tak potrebujete import 'babel-polyfill';

Rozšírenia pre Object


let person = {id: 42};

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

// {id: 42, name: 'ferko', surname: 'mrkvicka'}
                    
* Ak transpilujete cez babel, tak potrebujete import 'babel-polyfill';

Rozšírenia pre Array


Array.from(document.querySelectorAll("*")) // [...]
Array.from("foo")                          // ['f', 'o', 'o']
Array.of(1, 2, 3)                          // [1, 2, 3]
[0, 0, 0, 0].fill(7, 1, 2)                 // [0, 7, 0]
[1, 2, 3].findIndex(x => x == 2)        // 1
["a", "b", "c"].entries()                  // iterátor [0, "a"], [1,"b"], [2,"c"]
["a", "b", "c"].keys()                     // iterátor 0, 1, 2
["a", "b", "c"].values()                   // iterátor "a", "b", "c"
                    
* Ak transpilujete cez babel, tak potrebujete import 'babel-polyfill';

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


0b1011
0o715
                    

Promise


const p = new Promise(function (resolve, reject) {
    console.log('vytvaram promise');

    setTimeout(function () {
        console.log('resolvujem promise');
        resolve("foo");
    }, 1000);
});

p.then(function (msg){
    console.log(msg);
});
                    
Celkom fajn dokumentácia na MDN

Syntax sugar pre triedy a dedičnosť

Zlé nápady sa nemajú propagovať, takže o tomto pomlčím :)

ES2016

Iba dve veci:


// Array.prototype.includes
['a', 'b', 'c'].includes('a') // true
['a', 'b', 'c'].includes('d') // false

// Exponenčný operátor
2 ** 3 // 8
                    

ES2017

Ešte ďalej

Rest/Spread operátor pre objekty


// Rest
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
console.log(x); // 1
console.log(y); // 2
console.log(z); // { a: 3, b: 4 }

// Spread
let n = { x, y, ...z };
console.log(n); // { x: 1, y: 2, a: 3, b: 4 }
                    
Super užitočné a návykové, ale je potrebný babel plugin transform-object-rest-spread

Ďakujem za pozornosť

Otázky?