KEMBAR78
JavaScript Futures—ES2017 and Beyond | PDF
#jsFutures
E S 2 0 1 7 A N D T H E R O A D A H E A D
@ j e f f r e y s t r a u ss
“ JavaScript just
keeps on expanding!
expanding
WHAT?
HOW?
WHY?
ECMAScript !== JS
ECMAScript2015
ECMAScript
2016
ECMAScript
2017
ES.Next
experiment
this is an ongoing evolution
ECMAScript
2016
features
features
exponentiation
let square = x => Math.pow(x, 2);
let cube = x => Math.pow(x, 3);
console.log(square(3)); // 9
console.log(cube(4)); // 64
ES2015:
**
let square = x => Math.pow(x, 2);
let cube = x => Math.pow(x, 3);
square(3); // 9
cube(4); // 64
ES2015:
let square = x => x ** 2;
let cube = x => x ** 3;
square(3); // 9
cube(4); // 64
ES2016:
assignment
let x = 10;
x = Math.pow(x, 3); // x === 1000
ES2015:
let x = 10;
x = Math.pow(x, 3); // x === 1000
ES2015:
let x = 10;
x **= 3; // x === 1000
ES2016:
Array.prototype.includes
let someArray = [1, 2, 3, 'foo', false, NaN];
someArray.indexOf('foo') !== -1;
ES2015:
let someArray = [1, 2, 3, 'foo', false, NaN];
someArray.indexOf('foo') !== -1;
someArray.indexOf(NaN) !== -1; // Uh-oh, returns false
ES2015:
let someArray = [1, 2, 3, 'foo', false, NaN];
someArray.indexOf('foo') !== -1;
someArray.indexOf(NaN) !== -1; // Uh-oh, returns false
ES2015:
let someArray = [1, 2, 3, 'foo', false, NaN];
someArray.includes('foo'); // returns true
someArray.includes(NaN); // returns true
ES2016
let someArray = [1, 2, 3, 'foo', false, NaN];
someArray.indexOf('foo') !== -1;
someArray.indexOf(NaN) !== -1; // Uh-oh, returns false
ES2015:
let someArray = [1, 2, 3, 'foo', false, NaN];
someArray.includes('foo'); // returns true
someArray.includes(NaN); // returns true
someArray.includes('foo', 4); // returns false
ES2016
let someArray = [1, 2, 3, 'foo', false, NaN];
someArray.indexOf('foo') !== -1;
someArray.indexOf(NaN) !== -1; // Uh-oh, returns false
ES2015:
let someArray = [1, 2, 3, 'foo', false, NaN];
someArray.includes('foo'); // returns true
someArray.includes(NaN); // returns true
someArray.includes('foo', 4); // returns false
ES2016
ECMAScript
2017
Object static methods
Object.values(obj)
let boy = { name: 'Keller', age: 6 };
let values = Object.values(boy);
console.log(values);
// ['Keller', 6]
ES2017:
Object.entries(obj)
let girl = { name: 'Madeleine', age: 2.9 };
let entries = Object.entries(girl);
console.log(entries);
// [ ['name', 'Madeleine'], ['age', 2.9] ]
ES2017:
let family = {
dad: 'Jeff',
mom: 'Jamie',
boy: 'Keller',
girl: 'Madeleine'
};
ES2017:
let family = {
dad: 'Jeff',
mom: 'Jamie',
boy: 'Keller',
girl: 'Madeleine'
};
for (const [k, v] of Object.entries(family)) {
// iterate over and do something with properties
}
ES2017:
string padding
let team = ['Jeff', 'Jon'];
team.forEach(p => console.log(p));
// Jeff
// Jon
ES2017:
padStart(max[, fill])
let team = ['Jeff', 'Jon'];
team.forEach(p => console.log(p.padStart(8));
// Jeff
// Jon
ES2017:
let team = ['Jeff', 'Jon'];
team.forEach(p => console.log(p.padStart(8, '-'));
// ----Jeff
// -----Jon
ES2017:
let team = ['Jeff', 'Jon'];
team.forEach(p => console.log(p.padStart(8, 'ab'));
// ababJeff
// ababaJon (partial snippet of fill mask)
ES2017:
padEnd(max[, fill])
trimStart / trimEnd
async & await
function chainCallbacks() {
loadData(function(a) {
loadOtherData(a, function(b) {
processTheData(b, function(c) {
saveData(c, function(d) {
console.log(d);
});
});
});
});
}
PRE-ES2015
function chainPromises() {
loadData()
.then(a => loadOtherData(a))
.then(b => processTheData(b))
.then(c => saveData(c))
.then(d => console.log(d));
}
ES2015 (PROMISES)
async function awaitCalls() {
const a = await loadData();
const b = await loadOtherData(a);
const c = await processTheData(b);
const d = await saveData(c);
console.log(d);
}
ES2017 (ASYNC/AWAIT)
async function awaitCalls() {
try {
const a = await loadData();
const b = await loadOtherData(a);
const c = await processTheData(b);
const d = await saveData(c);
console.log(d);
} catch(ex) {
// handle the error
}
}
ES2017 (ASYNC/AWAIT)
wraps in promise
async function awaitCalls() {
const a = await loadData();
const b = await loadOtherData(a);
const c = await processTheData(b);
const d = await saveData(c);
return d; // wraps d in Promise
}
awaitCalls().then(response => {
console.log(response); // response resolves to d
});
ES2017 (ASYNC/AWAIT)
multiple prerequisites
function multiSetProcess() {
let a = loadDataSet1();
let b = loadDataSet2();
Promise.all([a, b]).then(results => {
processTheData(...results).then(c => {
console.log(c);
});
});
}
ES2015
async function multiSetProcess() {
const a = await loadDataSet1();
const b = await loadDataSet2();
console.log(await processTheData(a, b));
}
ES2017
async function multiSetProcess() {
const a = loadDataSet1();
const b = loadDataSet2();
console.log(await processTheData(await a, await b));
}
ES2017
await "at the top"
// app.js
console.log(await someAsyncCall());
ⓧ Uncaught SyntaxError: Unexpected identifier
ES2017
// app.js
(async () => {
console.log(await someAsyncCall());
})();
ES2017
other
stuff
TRAILING COMMAS
DESCRIPTORS
SHARED MEMORY
ATOMICS
ES.Next
“Wow, what else
is coming?
“All kinds of stuff!
Eventually...
rest & spread properties
async iteration
regex enhancements
observables
public & private fields
EUROPEAN
COMPUTER
MANUFACTURERS
ASSOCIATION
ECMA-262
TC39
TC39
MOZILLA
GOOGLE
MICROSOFT
INTEL
JQUERY
the TC39 process
stages
strawman
input to process
proposal
rationale • solution • challenges
draft
syntax • semantics • formal spec
candidate
implementations • feedback
finished
ready for inclusion
seeing the future
so many proposals
github.com/
tc39/ecma262
proposals
FINISHED
ACTIVE
STAGE 0
INACTIVE
github.com/
tc39/test262
github.com/rwaldron/
tc39-notes
implementations
bit.ly/es6-compat
DISCUSS
W H E R E T O G O F R O M H E R E
educate
invest
empower
#jsFutures
j e f f r e y . s . s t r a u ss @ g m a i l . c o m
@ j e f f r e y s t r a u ss

JavaScript Futures—ES2017 and Beyond