The Beautiful Simplicity of ES2015

Post on 07-Apr-2017

301 views 1 download

Transcript of The Beautiful Simplicity of ES2015

The Beautiful Simplicityof ES2015

Brandon Belvin

What is ES2015?

● Code-named "Harmony;" contains many improvements that were slated for the fourth edition of ECMAScript (commonly known as JavaScript)

● Began in 2008, but was scaled back and delayed after dissent

● Re-emerged in 2011 to become the sixth edition, known as ES6

● Finalized in June 2015, renamed to ES2015

● Annual updates planned with ES2016 and ES2017 roadmapped

But what makes ES2015 so great?...

Arrow Functions

Features

● Terse, yet expressive

● Bound to lexical scope

● Make great sense when following functional programming

What They Solve

● Perfect for small, in-line anonymous functions

● Less var self = this; and.bind(this)

[1,2,3].reduce((acc,val) => acc + val);

[1,2,3].reduce(function(acc, val) {

return acc + val;

});

Arrow Functions

ES6

ES5

[1,2,3].reduce((acc,val) => acc + val);

Arrow Functions

[1,2,3,4,5,6].filter(val => val !== 5) //[1,2,3,4,6]

.map((val, i) => val * i) //[0,2,6,12,24]

.reduce((prev, cur) => prev + cur); //44

(This is in no way a contrived example… It's completely serious.)

Template Strings

Features

● Native interpolation

● Multi-line strings

● Custom template processors

What They Solve

● No need to escape tick or quote

● No more:

'Looped ' + count + ' times'

'foo\n' +'bar\n' +'baz'

`The time and date is ${ new Date().toLocaleString() }`

var apples = 5;var text = 'Bob ate ' + apples + ' of his apples!';console.log(text);// Bob ate 5 of his apples!

Template Strings

ES5

ES6var howMany = apples => apples > 4 ? 'so many' : 'a few';var apples = 5;var text = `Bob ate ${ howMany(apples) } apples!`;console.log(text);// Bob ate so many apples!

Template StringsMulti-linevar multiLineText = `This ismulti-line and continuesuntil the nextbacktick`;

// This is// multi-line and continues// until the next// backtick

Function Interpolationvar list = [ 1, 2, 3 ];var template = `<div><ul>${list.map(num => `<li>${num}</li>`).join('\n')}</ul></div>`;

// <div><ul>// <li>1</li>// <li>2</li>// <li>3</li>// </ul></div>

Assignment Destructuring

Features

● Easier variable assignment

● Can access deep properties in objects

● Assignment and index skipping for arrays

What They Solve

● No more huge blocks of assignment boilerplate

● Destructuring as a parameter list

var { baseUrl, body, params: { id } } = request;

Assignment Destructuring

ES5var baseUrl = request.baseUrl;var body = request.body;var pageId = request.params.id;

ES6var { baseUrl, body, params: { id: pageId } } = request;

Default and Rest Parameters, Spread Operator

Features

● Can set a default argument value

● Collect multiple arguments into an array

● Can also destructure arrays

What They Solve

● Set a default value rather than checking for existence inside the function

● Can be used instead of the arguments object (which isn't a real array)

● Can replace the .apply() function

function foo (bar=12, ...rest) { var ary = [1, 2, ...rest]; }

Default and Rest ParametersES5function sum() { if (!arguments.length) { return 0; } var args = Array.prototype.slice.call(arguments); var base = args.shift(); return args.reduce(function (prev, val) { return prev + val; }, base);} // 8 lines inside sum()

sum(); // 0sum(5); // 5sum(1,2,3,4,5,6,7); // 28

Default and Rest ParametersES5 (Improved)function sum() { var args = Array.prototype.slice.call(arguments); var base = args.shift(); return args.reduce(function (prev, val) { return prev + val; }, base || 0);} // 5 lines inside sum()

sum(); // 0sum(5); // 5sum(1,2,3,4,5,6,7); // 28

Default and Rest ParametersES6function sum(base = 0, ...vals) { return vals.reduce((prev, val) => prev + val, base);} // 1 line inside sum()

sum(); // 0sum(5); // 5sum(1,2,3,4,5,6,7); // 28

var x = new (Date.bind.apply(Date, [null, 2015, 9, 23]));console.log(x.toDateString());// Fri Oct 23 2015

Spread Operator

ES5

ES6var x = new Date(...[2015, 9, 23]);console.log(x.toDateString());// Fri Oct 23 2015

(Hat-tip to Nicolas Bevacqua for this example)

Promises

Features

● Allows for more narrative asynchronous code

● "Proper" exception handling

● Easier to follow for complex asynchronous interactions through chaining

What They Solve

● Eliminate "callback spaghetti"

● Can throw exception rather than return it in callback

fetch('foo').then(res => {}).catch(err => {})

Callback ExampleUser.findById('bob_appleseed', function(err, user) { if (err) { return console.log(`error: ${ err }`); } user.apples = user.apples - 5;

user.save(function(err, user) { if (err) { return console.log(`error: ${ err }`); } console.log(`Bob now has ${ user.apples } apples`); });});

PromisesUser.findById('bob_appleseed').exec() .then(user => { user.apples = user.apples - 5;

return user.save(); // returning a promise here }) .then(user => { console.log(`Bob now has ${ user.apples } apples`); }) .catch(err => { // Only need one catch for this chain console.log(`error: ${ err }`); });

PromisesExtra Features

Promises.all([ fetch('api.random.org'), fetch('api.random.org') ]) .then(randoms => randoms.reduce((prev, val) => prev + val, 0) / randoms.length; }) .catch(err => `Randoms request failed with error: ${ err }`);

Promise.all() - Wraps an array of Promises in a Promise that either resolves when all the dependencies resolve, or rejects if any of the dependencies reject.

● Useful when a function should only run after a number of parallel async operations are complete

PromisesExtra Features

Promise.race([ fetch('/resource-that-may-take-a-while'), new Promise((resolve, reject) => setTimeout(() => reject(new Error('request timeout')), 5000) )]).then(response => console.log(response)).catch(error => console.log(error));

Promise.race() - Accepts an array of Promises and settles with the value of the first to complete.

● Can be used to handle timeout of a Promise we otherwise have no control over:

(Another very grateful hat-tip to Nicolas Bevacqua for this example)

And this only scratches the surface...

Assignment Destructuring

Spread Operator

Rest Parameters

Arrow Functions

Template Strings

Object Literals

Classes

Let and ConstSymbols

IteratorsGenerators

Promises

Maps/WeakMaps

Sets/WeakSets

Proxies

Reflection

Modules

How to use ES2015 today

100% support is still a long way off, but you can use most of the enhancements today.

Built-in Support:

● Node v4 (more with --harmony flag)

● Chrome● Firefox● Microsoft Edge

Transpiler:

● Babel (babeljs.io)

● Traceur (google/traceur-compiler)

Where to learn ES2015

Blogs & Writing:

● PonyFoo (ponyfoo.com)

● JavaScript Scene (medium.com/javascript-scene)

● Babel Docs (babeljs.io/docs/learn-es2015)

Docs & Resources:

● Mozilla Developer Network (MDN)

● Learn Harmony (learnharmony.org)