BEYOND ES6
New possibilities of JavaScript and how to use them


SYLWIA LASKOWSKA

JavaScript
EcmaScript
JavaScript
Created by Brendan Eich in 1995
Ecma-262 standard
JScript
ActionScript
2009 - ES5
2015 - ES6
2016 - ES2016,
2017 - ES2017,
2018 - ES2018,
2019 - ES2019,
....

Who, what, when, how?
How are new features created?

Technical Committee 39
JavaScript developers, implementers, academics, and more, collaborating with the community to maintain and evolve the definition of JavaScript.
All major browser vendors.
Meet 6 times a year.
ES2016 (ES7)
Array.prototype.includes
Syntax:
var boolean = arr.includes(searchElement[,fromIndex])
myFavoriteBeers = ['Pearl', 'TurboBeer', 'BeerScript']
myFavoriteBeers.includes('TurboBeer');
// true
myFavoriteBeers.includes('kitty');
// false
myFavoriteBeers.includes('BeerScript', 1);
// true
myFavoriteBeers.includes('Pearl', 5);
// false
Exponentiation operator
operand ** operand
const beerPack = 4;
let beerPackChain = Math.pow(beerPack, 2);
// is now
beerPackChain = beerPack ** 2 // 16

ES2017 (ES8)
Async functions
Callback Hell (ES5)
const userCity = 'https://ourfakeapi.pl/usercity';
const bestBeerInTheCity = 'https://ourfakeapi.pl/city?name=';
const beerFans = 'https://ourfakeapi.pl/fans?beer=';
function getBeerFans() {
request(userCity, function(result) {
request(bestBeerInTheCity + result), function(result) {
request(beerFans + result), function(result) {
console.log("Help!!! How did we end up like this???");
}
}
})
}

Async functions
Promises (ES6)
const userCity = 'https://ourfakeapi.pl/usercity';
const bestBeerInTheCity = 'https://ourfakeapi.pl/city?name=';
const beerFans = 'https://ourfakeapi.pl/fans?beer=';
function getBeerFans() {
return axios.get(userCity)
.then((response) => {
return axios.get(`bestBeerInTheCity${response}`);
})
.then((response) => {
return axios.get(`beerFans${response}`)
})
.then((response) => {
console.log('Ok, not so bad!');
});
}

Async functions
Async - await (ES8)
const userCity = 'https://ourfakeapi.pl/usercity';
const bestBeerInTheCity = 'https://ourfakeapi.pl/city?name=';
const beerFans = 'https://ourfakeapi.pl/fans?beer=';
async function getBeerFans() {
const city = await axios.get(userCity);
const bestBeer = await axios.get(`bestBeerInTheCity${city}`);
const fans = await axios.get(`beerFans${bestBeer}`);
console.log('That is all code we need!');
}

Object.entries()
let beerPrices = {
beer1: 5,
beer2: 6,
beer3: 8
}
let beersIntoEntries = Object.entries(beerPrices);
// [['beer1', 5], ['beer2', 6], ['beer3', 8]]
let priceInCapitalCity = beersIntoEntries
.map(([key, value]) => [key, value * 2]);
// [['beer1', 10], ['beer2', 12], ['beer3', 16]]

Object.values()
let beers = {
beer1: 'white',
beer2: 'brown',
beer3: 'yellow'
}
let beerColors = Object.values(beers);
// ['white', 'brown', 'yellow']
let adv = `Our beers are: ${beerColors.join(', ')}`;
// Our beers are: white, brown, yellow
Object.getOwnPropertyDescriptors()
favoriteBeer = {
name: 'Gold Tiger',
type: 'stout',
logName: () => console.log(this.name)
}
Object.getOwnPropertyDescriptors(favoriteBeer);
/*
{name: {…}, type: {…}, logName: {…}}
logName: {value: ƒ, writable: true, enumerable: true, configurable: true}
name: {value: "Gold Tiger", writable: true, enumerable: true, configurable: true}
type: {value: "stout", writable: true, enumerable: true, configurable: true}
__proto__: Object
*/
Object.getOwnPropertyDescriptors()
favoriteBeer = {
name: 'Gold Tiger',
type: 'stout',
set description(desc) {
console.log(desc);
}
}
const favoriteBeer2 = Object.assign({}, favoriteBeer);
// {name: "Gold Tiger", type: "stout", description: undefined}
const favoriteBeer3 = Object.defineProperties({},
Object.getOwnPropertyDescriptors(favoriteBeer));
// {name: "Gold Tiger", type: "stout"}
favoriteBeer3.description = 'It is my favorite beer!';
// It is my favorite beer!
Other features
Shared memory and atomics
Trailing commas
String.prototype.padStart/padEnd
ES2018 (ES9)
...Rest properties for objects
let {name, id, ...remaining} = {
name: 'Sylwia',
id: '123456',
favouriteBeer: 'Bar Free',
city: 'Gdansk',
age: 60
}
name; // Sylwia
id; // '123456'
remaining; // {favouriteBeer: 'Bar Free', city: 'Gdansk', age: 60}

...Spread properties for objects
const data = {name: 'Sylwia', id: '123456'};
const favourites = {favBeer: 'Xxx', favBar: 'The Cheapest'};
const oneBigObj = {...data, ...favourites};
// {name: 'Sylwia', id: '123456', favBeer: 'Xxx', favBar: 'The Cheapest'}

Promise.prototype.finally()
let loading = true;
axios.get('https://somefakeapiagain.pl/myFavouriteBeer')
.then(resp => doSthWithResp(resp))
.catch(err => handleError(err))
.finally(() => {
loading = false;
// This will always be executed
})

Other features
Async iterators
RegExp named capture groups
RegExp unicode property escapes
RegExp lookbehind assertions
s (dotAll) flag for regular expressions
Template literal revision
ES2019 (ES10)
Array.prototype.flat()
let nestedBeerArray = ['beer1', 'beer2', ['beer3', 'beer4']];
nestedBeerArray.flat();
// ['beer1', 'beer2', 'beer3', 'beer4']
let beerIndexes = [1, 2, [3, 4, [5, 6, [7, 8]]]];
beerIndexes.flat(2);
// [1, 2, 3, 4, 5, 6, [7, 8]];
beerIndexes.flat(Infinity);
// [1, 2, 3, 4, 5, 6, 7, 7];

Array.prototype.flatMap()
const normalBeers = ['Pulsner', 'Golden Tiger'];
let normalAndLight = normalBeers.map(beer => [beer, `${beer} Light`]));
// [['Pulsner', 'Pulsner Light'], ['Goldern Tiger', 'Golden Tiger Light']];
normalAndLight = normalBeers.flatMap(beer => [beer, `${beer} Light`]));
// ['Pulsner', 'Pulsner Light', 'Goldern Tiger', 'Golden Tiger Light'];

Object.fromEntries()
let beerPrices = {
beer1: 5,
beer2: 6,
beer3: 8
}
let beersIntoEntries = Object.entries(beerPrices);
// [['beer1', 5], ['beer2', 6], ['beer3', 8]]
let priceInCapitalCity = beersIntoEntries.map(([key, value]) => [key, value * 2]);
// [['beer1', 10], ['beer2', 12], ['beer3', 16]]
// LET THE MAGIC HAPPEN!!!
let doublePriceObj = Object.fromEntries(priceInCapitalCity);
{
beer1: 10,
beer2: 12,
beer3: 16
}
Other features
String.prototype.trimStart
String.prototype.trimEnd
Optional catch binding
Symbol.prototype.description
Array.prototype.sort() is now required to be stable
Well-formed JSON.stringify
JSON superset
Function.prototype.toString revision
What's next?
Dynamic import()
BigInt
Private class field
Can I use it?
Who are your clients?
What browsers do you need to support?
Polyfills/transpilers to the rescue
Thank you!
Meet.js Summit 2019
By sylwia_lask
Meet.js Summit 2019
Beyond ES6 - how to use the features?
- 357