javascript in 2016 (codemotion rome)

65
JavaScript in 2016 Eduard Tomàs @eiximenis ROME 18-19 MARCH 2016

Upload: eduard-tomas

Post on 21-Jan-2018

1.123 views

Category:

Technology


0 download

TRANSCRIPT

JavaScript in 2016

Eduard Tomàs

@eiximenis

ROME 18-19 MARCH 2016

Who am I?

Beer lover & crafter

Who am I?

Happy and proud father

Who am I?

Nerdy speaker ^_^

Who am I?

Developer @

• About JavaScript

• How it was

• How it is now

• How it will be in the (near) future

What i will talk about?

No excuses to not use ES2015 now

Most featuresalready implementedin modern browsers

For everything else… Babel

• Invented 20 years ago (1995) by Brendan Eich (in Netscape) for using mainly as a scripting Language

• Currently in version 6 (this is the version we willtalking about)• Version 6 is from 2015

• Previous version 5 is from 2009

• A lot of people still don’t use all version 5 features!

A bit of history...

• Getters and Setters

• strict mode

• Reflection

Underused v5 features

• A lot of new features...

• Three groups of features

• Minor improvements (mostly syntax sugar)

• New Language core features

• Other features

ECMAScript 2015 (aka v6)

• A lot of new features...

• Three groups of features

• Minor improvements (mostly syntax sugar)• String interpolation, arrow functions, binary and octal literals, block

scope, enhanced object notation, new types (map, set, typed arrays)

• New Language core features• Symbols, Iterators and generators, destructuring, classes

• Other features• Promises, Modules, Proxies

ECMAScript 2015 (aka v6)

• A lot of new features...

• Three groups of features

• Minor improvements (mostly syntax sugar)• String interpolation, arrow functions, binary and octal literals, block

scope, enhanced object notation, new types (map, set, typed arrays)

• New Language core features• Symbols, Iterators and generators, destructuring, classes

• Other features• Promises, Modules, Proxies

ECMAScript 2015 (aka v6)

Ready?

• A new, compact and cleaner syntax for creating a function

Arrow Functions

function (i) {return i*2;

}

i => i*2

• Very compact, easy to read

• A new, compact and cleaner syntax for creating a function

• And they come with a gift: arrow operator preserves context!

Arrow Functions

var Brewery = function(name) {this.name = name;this.beers = [];this.getBeersWithFullName = function() {

return this.beers.map(function(element) {return {

name: element.name + " by " + this.name,style: element.style};

});}

}

• A new, compact and cleaner syntax for creating a function

• And they come with a gift: arrow operator preserves context!

Arrow Functions

var Brewery = function(name) {this.name = name;this.beers = [];this.getBeersWithFullName = function() {

return this.beers.map(function(element) {return {

name: element.name + " by " + this.name,style: element.style};

}.bind(this));}

}

• A new, compact and cleaner syntax for creating a function

• And they come with a gift: arrow operator preserves context!

Arrow Functions

var Brewery = function(name) {this.name = name;this.beers = [];this.getBeersWithFullName = function () {

return this.beers.map(e => ({name: e.name + " by " + this.name,style: e.style

}));}

}

But be aware...

var x = {nick: '1. eiximenis',identify: () => console.log('I am ' + this.nick)

}

x.identify();

var X = function () {this.nick = '2. eiximenis';this.identify = () => console.log('I am ' + this.nick)

}

new X().identify();

• Pipe operator – Only syntax, but matters!

Maybe in the (near) future (ES7)...

function doubleSay(str) {return str + ", " + str;

}function capitalize(str) {

return str[0].toUpperCase() + str.substring(1);}function exclaim(str) {

return str + '!';}

let result = exclaim(capitalize(doubleSay("hello"))); // Hello, hello!

let result = "hello"|> doubleSay |> capitalize |> exclaim;

Destructuring

• You have an array with two values.

• How to assign these two values to two independent variables?

var values = [42, 69];var x = 42;var y = 69;

var values = [42, 69];var [x,y] = values;

• Works with objects too

Destructuring

let obj = {a:10, b: 30, c:'Hello'};

let {a:x, c:y} = obj;

• Very easy to extract partial info of an object

let user= {name:'eiximenis', beers:[{id: 1, name: 'Moretti'},

{id: 2, name: 'Epidor'}], city: 'Igualada'

};

let {name, beers: [,epidor]} = user;

• A very powerful operator that maps to “the rest values of an iterable”

• Key concept is “rest” (only values not yet iterated areapped to the array)

Spread operator

var lost = [4, 8, 15, 16, 23, 42];var [,eight,fifteen,...others] = lost;

• Spread operator also maps an array to a N arguments in a function

• A new fresh way to call functions from arrays withoutneed for apply

• In fact is far more powerful than apply...

Spread operator

let foo = function (a, b, c, d, e) { }foo(10, ...[20, 30], 40, ...[50]);

• Last parameter of function can be prepended withspread operator

• This parameter will contain an array with all extra parameters passed to this function

Rest parameters

• It is like arguments but better...• It is really an array

• Only contains non-named parameters

var foo = function (a, b, ...c) { }foo(1, 1, 2, 3, 5);

Iterators and generators

• An iterator enables custom iteration over an object

• Is a function that returns an object (the iterator)

• Name of this function is Symbol.iterator

• Only one iterator per object

• Iterators are lazy, evaluated as values are needed

• Any object with an iterator is an iterable and• Can be iterated using for...of

• Spread operator can map the object to an array

Iterators

• It’s a bit cumbersone...

Need to declare Symbol.iterator as a function that

returns an object

with only one function

called next that returns

an object

with two properties

value (the current value)

done (true if iteration finished)

Creating an iterator

Creating an iterator

let fibonacci = {[Symbol.iterator]() {

let pre = 0, cur = 1;return {

next() {[pre, cur] = [cur, pre + cur];return { done: false, value: cur }

}}

}}

for (var n of fibonacci) {if (n > 1000)

break;console.log(n);

}

Generating iterators

for (var n of fibonacci) {if (n > 1000)

break;console.log(n);

}

var fibonacci = {[Symbol.iterator]: function*() {

let pre = 0, cur = 1;for (;;) {

[pre, cur] = [cur, pre + cur];yield cur;

}}

}

• Generators can be objects by themselves

• Can create a function that is a generator and iterateover its values

Generators

function* lost() {yield 4;yield 8;yield 15;yield 16;yield 23;yield 42;

}

[...lost()];

• A generator can yield all values of another generatorusing yield*

Chaining generators

function* lostrange(limit) {for (let idx=0; idx<limit;idx++) {

yield idx;yield* lost();

}}

var lost = function* () {yield 4;yield 8;yield 15;yield 16;yield 23;yield 42;

}

• but classes allow some specific features unavailable in ES5, so...

• Objects must be created with new and classes do notexist in runtime (typeof Point is ‘function’)

• This is equivalent to ES5 constructor pattern

Classes – The basics

class Point {constructor(x, y) {

this.x = x;this.y = y;

}toString() {

return '(' + this.x + ', ' + this.y + ')';}

}

• Properties (using the same ES5 get/set syntax)

• Inheritance (class Point3D extends Point)• Prototype of Point3D objects will be a Point object

• Static methods

• Classes define the constructor pseudo-method(invoked when object is creatred). • Derived constructors must call base to call the base

constructor before using this

• But still...

Classes – The basics

Classes

No private

methods!But (of course) we can fake them

• By defining all methods inside constructor as closures(ES5 way to do this)

Faking classes private methods

class SimpleDay {constructor(day) {

let _day = day;

this.getDay = function () {return _day;

}}

}

• By using Symbols to hide names

Faking classes private methods

let SimpleDay = (function () {let _dayKey = Symbol();class SimpleDay {

constructor(day) {this[_dayKey] = day;

}getDay() {

return this[_dayKey];}

}return SimpleDay;

}());

• By using Weak Map (preferred way)

Faking classes private methods

let SimpleDay = (function () {let _days = new WeakMap();

class SimpleDay {constructor(day) {

_days.set(this, day);}getDay() {

return _days.get(this);}

}return SimpleDay;

}());

• By using Weak Map (preferred way)

Faking classes private methods

let SimpleDay = (function () {let _days = new WeakMap();

class SimpleDay {constructor(day) {

_days.set(this, day);}getDay() {

return _days.get(this);}

}return SimpleDay;

}());

• External function can be avoided if using modules

• A function can return or receive a class

• This gives us an standard way of creating mixins

• Suppose a hierarchy of classes:

Classes are 1st class-citizens

class BarClass {bar() {

console.log('Bar from BarClass');}

}

class BazClass extends BarClass {baz() {

console.log('Baz from BazClass');}

}

Classes are 1st class-citizens

• We can declare a mixin:

let FooMixin = (sc) => class extends sc {foo() {

console.log('FooMixin method');}

}

• And apply it...

class BazFooClass extends FooMixin(BazClass) { }var bfc = new BazFooClass();bfc.bar(); // from superclass BarClassbfc.baz(); // from bazclassbfc.foo(); // from mixin

Modules

• Similar to CommonJS modules because

• Compact syntax

• Prefer single export

• Support for cyclic dependences

• Similar to AMD modules because

• Support for asynchronous module loading

• Configurable module loading

Modules ES6

Named exports

//------ lib.js ------export const sqrt = Math.sqrt;export function square(x) {

return x * x;}export function diag(x, y) {

return sqrt(square(x) + square(y));}

Any declaration prefixed by“export” keyword is an export of the module

Using import keyword we can choose what of the exports of the module we want to includeto the global namespace

//------ main.js ------import { square, diag } from 'lib';console.log(square(11)); // 121console.log(diag(4, 3)); // 5

Importing into namespace

//------ lib.js ------export const sqrt = Math.sqrt;export function square(x) {

return x * x;}export function diag(x, y) {

return sqrt(square(x) + square(y));}

Any declaration prefixed by“export” keyword is an export of the module

You can, of course, specify a namespace for the import, keepingthe global namespace clean

//------ main.js ------import * as lib from 'lib';console.log(lib.square(11)); // 121console.log(lib.diag(4, 3)); // 5

Did you notice the use of * to import all the exports of a module?

Default export

Module exports a class (note the useof default).

Default exports must be named on import

Module exports just a function

//------ MyClass.js ------export default class { ... };

//------ main2.js ------import MyClass from 'MyClass';let inst = new MyClass();

//------ myFunc.js ------export default function () { ... };

//------ main1.js ------import myFunc from 'myFunc';myFunc();

• Mean to be the “most important” export

• Represents “the module” itself

• A module can have one default and so many namedexports

Default and named exports

Module ‘react-native’has so many named exports (i. e. Image, Text) and also has thedefault export.

Default export is the most important and represents“the core of react”

This is a common pattern in JS (think about jQuery)

Modules

• Modules are statically defined and imported. CommonJS allows for:

This is not allowed in ES6

Less flexibility but no need to execute thecode to find the imports or exports of a module. Can be optimized.

var mylib;if (Math.random()) {

mylib = require('foo');} else {

mylib = require('bar');}

Promises

• No more callbacks needed

• Promise encapsulates the task and its State (pending, fulfilled or error found)

• Allows execution of code after its fulfillment or afteran error is found

• Can be chained

Promises – the basics

No more callback pyramid hell!

But be aware of thepromise pyramid hell!! :S

Promises - usage

var pxhr = xhrget('http://www.plainconcepts.com/');pxhr.then(function (req) {

console.log(req.responseText);});pxhr.catch(function(err) {

console.log('Oooops!');});

• Assume xhrget is a function that returns a Promise for loading a URL using GET

Promises – Sequential bad usage!

xhrget('https://httpbin.org/delay/4').then(() => {

console.log('1st downloaded');xhrget('https://httpbin.org/delay/3').then(() => {

console.log('2nd downloaded');xhrget('https://httpbin.org/delay/2').then(() => {

console.log('all download')})

})})

Promises – Sequential usage

xhrget('https://httpbin.org/delay/4').then(() => {

console.log ('1st downloaded');return xhrget('https://httpbin.org/delay/3');

}).then(() => {

console.log('2nd downloaded');return xhrget('https://httpbin.org/delay/2');}).

then(() => console.log('all downloaded'));

Promises – Parallel usage

Promise.all([xhrget('https://httpbin.org/delay/4'),(() => {

return xhrget('https://httpbin.org/delay/3');})(),(() => {

return xhrget('https://httpbin.org/delay/2');})()

]).then((reqs) => console.log(...(reqs.map(i => i.responseURL))));

Promises - creating

var xhrget = function (url) {var pr = new Promise(function (resolve, reject) {

var req = new XMLHttpRequest();req.open('GET', url, true);req.onreadystatechange = function () {

if (req.readyState == XMLHttpRequest.DONE) {if (req.status == 200) {

resolve(req);}else {

reject(new Error("Err " + req.status));}

}};req.send(null);

});return pr;

}

• Support for asynchronous will be in the core languagethrough async/await

• await -> a non-blocking wait over a promise. When anawait is found, code returns to its caller and when thepromise is fulfilled, the execution re-enters andcontinues after the await

In the (near) future (ES7)...

(async function() {doSomeSynchronousStuff();await loadStoryAsync();console.log("Done!");

}());

• Something similar could be done with ES6 withpromises and generators combined

• Develop using ES6

• Take a look on ES7 proposals!!!!

• Learn about reactive way to do things and even reactiveextensions• New frameworks and libs (Flux/Redux/Cyclejs but also Angular2)

are heavy based on this.

• Invest in TypeScript or flow if you would like to have statictyping in ES

• Learn some funcional language, it will help you as JS is everyday more functional

What to look next?

Questions?

Ask any questionyou have (no answeredguaranteed :P)

Thanks!

ROME 18-19 MARCH 2016

Eduard Tomàs - @eiximenis

Plain Concepts

http://www.plainconcepts.com

All pictures belong

to their respective authors