M&M – Mean Milano – Javascript



M&M – Mean Milano – Javascript

0 0


real-life-es6

Slide del talk "Real Life ES6" del 16 dicembre 2014

On Github MeanMilan / real-life-es6

M&M

Mean Milano

REAL LIFE ES6

  • Giovanni Lela
  • CTO @ LinkMe
  • Matteo Scandolo
  • MEAN Dev @ LinkMe

Javascript

An introduction

Javascript

is a dynamic computer programming language.

Javascript

  • is (kind of) object oriented
  • is functional
  • is event based

JavaScript

Was invented by Brendan Eich in May 1995. (in ten days and not in one night)

JavaScript

Has been developed for Netscape

And it has been realesed in Netscape 2 in September.

Maybe it was a bit immature...

  • x = 1.0000000000000001 (x === 1) // true
  • x = ['10', '10', '10']; x.map(parseInt) //[10, Nan, 2]

Javascript

Became an ECMA standard in 1997.

It is also know as ECMA-262

ECMAScript

Standard specification for the language

Derived languages born

  • ActionScript (Adobe)
  • JScript (Microsoft)

Versions

  • ES3 - 1999 (regEx - Try, Catch)
  • ES4 - tageted 2008, never saw the light...
  • ES5 - 2009 (Json, Bind, Map, ...)
  • ES6 - 2014?

Javascript Arise

Web 2.0 - Ajax - Google Maps (2005)

Js on the server - NodeJs (2009)

Why ES6?

Why change javascript?

  • Stagnation is a social ill
  • It breeds frustration
  • New solutions arise

Responding to stagnation

Some solutions are good

Others are bad

Evolving the standard is best

Everybody is going to ship javascript

Road to ES6

Some interesting Features

Template Strings

Allows string literals with embedded expressions in them.

var name = "Matteo"; console.log(`Hello, ${name}!`);

In Practice

<div id="js-element">initial content</div> <script> var name = "Matteo"; var element = document.getElementById('js-element'); element.innerHTML = `Hello, ${name}!`; </script>

Default Parameter Value

Default parameter values allow you to initialize parameters if they were not explicitly supplied. This means that you no longer have to do x = x || {};

var f = function(x = 5){return x + 1};

In Practice

var getUser = function(id = 'me'){     $.get('api/user/' + id,         function(res){return res},         function(e){throw new Error(e)}     ); }

Arrow Functions

The goal of Arrow Functions is to address and resolve several common pain points of traditional Function Expression:

  • Lexical this binding
  • Shorter syntactical form
//before var f = function(x){return x + 1;} //es6 var f = x => x+1; console.log(f(2));

In Practice

var user; getUser() .then(     res => user = res,     e => throw new Error(e) );

REST

Rest parameters provide a cleaner way of dealing with functions that takes arbitrary number of parameters than using arguments. Basically your parameters are convertend in an array

var f = function(...args){     var tot = 0;     for (var i = 0; i < args.length; i++ ){         tot += args[i];     }     return tot/args.length; } f(12, 8, 16, 32); //17

In Practice

var cart = {list: []}; cart.add = function(...items){     items.forEach(item => this.list.push(item)); }; cart.add('ball'); cart.add('tree', 'soap'); console.log(cart.list);

SPREAD

The spread construct allows an expression to be expanded in places where multiple arguments are expected

var args = [12, 99, 17] var f = (x, y, z) => Math.min(x, y, z); f(...args);

In practice

var inputs = [1,2,3]; function f(x, y, z) {     return x + y + z; } f(...inputs);

In Practice

This example rely on Bluebird and Lodash

var targetFunction = _.curry(function(a,b,c)); targetFunction('Hello'); var functionList = [fn1, fn2]; // fn1 => return name | fn2 => return surname; Promise //bluebird .all(functionList) //accept an array of Promise .then( function(res){ //receive an array     //spread the array into arguments     targetFunction(...res); });

Road to ES6

Some more interesting Features

Block scoping

Hoisting

function f() {     doSomething();     var a = 1; } function f() {     var a;     doSomething();     a = 1; }
for (var i = 0; i < 3; i++) {     var j = 1 * i;     console.log(j); //0 //1 //2 } console.log(j); // 3 for (var i = 0; i < 3; i++) {     let j = 1 * i;     console.log(j); //0 //1 //2 } console.log(j); // will throw ReferenceError

Dangers of hoisting

Don't make functions within a loop

var elems = document.getElementsByClassName('myClass'), i; for (i = 0; i < elems.length; i++) {     elems[i].addEventListener('click', function () {         this.innerHTML = i;     }); }

Before: ugly scoping magic

var elems = document.getElementsByClassName('myClass'), i; function makeClickHandler(i) {     return function () {         this.innerHTML = i;     }; } for (i = 0; i < elems.length; i++) {     elems[i].addEventListener("click", makeClickHandler(i)); }

Now: let to the rescue

for (let i = 0; i < elems.length; i++) {     elems[i].addEventListener("click", function () {         this.innerHTML = i;     }); }

Const

The same as let but:

  • It must be initialized
  • And just once
const CONSTANT; //error const CONSTANT = "Wow, I am constant"; CONSTANT = "No you are not"; //error

Iterators, generators and the callback hell

Iterator

An Iterator is an object that knows how to access items from a collection one at a time, while keeping track of its current position within that sequence

var lang = { name: 'JavaScript', birthYear: 1995 }; var it = Iterator(lang); var pair = it.next(); // Pair is ["name", "JavaScript"] pair = it.next(); // Pair is ["birthYear", 1995] pair = it.next(); // A StopIteration exception is thrown

Iterable

function Words(str) {     this._str = str; } Words.prototype[Symbol.iterator] = function() {     var re = /\S+/g;     var str = this._str;     return {         next: function() {             var match = re.exec(str);             if (match) {                 return {value: match[0], done: false};             }             return {value: undefined, done: true};         }     } };

for..of

var helloWorld = new Words("Hey you"); for (var word of helloWorld) {     console.log(word); } //Hey //you

Works also on arrays, maps, sets..

Generators

  • A very special kind of iterators
  • It's an iterator whose results are determined by an iterator function

Iterating on a generator

function* countdown(){     yield 2; //first next()     yield 1; //second next()     yield 0; //third next()     //done } let generatorObject = countdown(); generatorObject.next(); // {value : 2, done : false} generatorObject.next(); // {value : 1, done : false} generatorObject.next(); // {value : 0, done : false} generatorObject.next(); // {value : undefined, done : true}

Talking back to a generator

function* countdown(){     let one = yield 2; //first next()     console.log(one); //one     let two = yield 1; //second next     console.log(two); //two     let three = yield 0; //third next     console.log(three); //three     //done! } let generatorobject = countdown(); generatorobject.next(); // {value : 2, done : false} generatorobject.next('one'); // {value : 1, done : false} generatorobject.next('two'); // {value : 0, done : false} generatorobject.next('three'); // {value : undefined, done : true}

Hello promises

  • A promise is an object which represents the results of a future computation
  • It allows to take action when the async operation is done

Using a promise

var awesomePromise = getAsyncThings(); awesomePromise.then(     //resolve     function(value){         console.log('yeah :' + value);     },     //reject     function(error){         console.log('oh no');         console.log(error);     } );

Creating a promise

function getAsyncThings(url) {     // Return a new promise.         return new Promise(function(resolve, reject) {             // Do the usual XHR stuff             var req = new XMLHttpRequest();             req.open('GET', url);             req.onload = function() {                 // This is called even on 404 etc so check the status                 if (req.status === 200) {                     // Resolve the promise with the response text                     resolve(req.response);                 }                 else {                     // Otherwise reject with the status text which will hopefully be a meaningful error                      reject( new Error(req.statusText));                 }             };         // Handle network errors         req.onerror = function() {             reject( new Error('Network Error'));         };         // Make the request         req.send();     }); }

Chaining promises

getStuff('stuff.json') .then(function(story){     return saveInSomeDatabase(); }) .then(function(success){     console.log('saved!'); });

Promises + generators = ..

var gen = generator(); //get the party started var generatedPromise = gen.next().value; //when the promise is resolved call the next step function nextStep(){     generatedPromise.then(function(promiseResult){         gen.next(promiseResult);     }); } //loop me nextStep();

(Semi) coroutines

Promise.coroutine(function* () {     var tweets = yield $.get('tweets.json');     var profile = yield $.get('profile.json');     var friends = yield $.get('friends.json');     console.log(tweets, profile, friends); })();

Suggested readings

Server Side JS

  • Real Life examples on Server Side programming
  • 20th January 2015 - 7:00 pm
  • Place to be defined

M&M Milano !== LinkMe

But...we are looking for an experienced Node Developer

Write @ jobs@link-me.it