the beautiful simplicity of es2015

26
The Beautiful Simplicity of ES2015 Brandon Belvin

Upload: brandon-belvin

Post on 07-Apr-2017

300 views

Category:

Software


1 download

TRANSCRIPT

Page 1: The Beautiful Simplicity of ES2015

The Beautiful Simplicityof ES2015

Brandon Belvin

Page 2: The Beautiful Simplicity of ES2015

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

Page 3: The Beautiful Simplicity of ES2015

But what makes ES2015 so great?...

Page 4: The Beautiful Simplicity of ES2015

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);

Page 5: The Beautiful Simplicity of ES2015

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

return acc + val;

});

Arrow Functions

ES6

ES5

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

Page 6: The Beautiful Simplicity of ES2015

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.)

Page 7: The Beautiful Simplicity of ES2015

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() }`

Page 8: The Beautiful Simplicity of ES2015

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!

Page 9: The Beautiful Simplicity of ES2015

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>

Page 10: The Beautiful Simplicity of ES2015

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;

Page 11: The Beautiful Simplicity of ES2015

Assignment Destructuring

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

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

Page 12: The Beautiful Simplicity of ES2015

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]; }

Page 13: The Beautiful Simplicity of ES2015

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

Page 14: The Beautiful Simplicity of ES2015

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

Page 15: The Beautiful Simplicity of ES2015

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

Page 16: The Beautiful Simplicity of ES2015

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)

Page 17: The Beautiful Simplicity of ES2015

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 => {})

Page 18: The Beautiful Simplicity of ES2015

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`); });});

Page 19: The Beautiful Simplicity of ES2015

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 }`); });

Page 20: The Beautiful Simplicity of ES2015

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

Page 21: The Beautiful Simplicity of ES2015

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)

Page 22: The Beautiful Simplicity of ES2015

And this only scratches the surface...

Page 23: The Beautiful Simplicity of ES2015

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

Page 24: The Beautiful Simplicity of ES2015

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)

Page 25: The Beautiful Simplicity of ES2015

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)