ES2015

es.next

HARMONY

es6

ECmA international

European Computer Manufacturers Association
Organização internacional focada em padronização de sistemas de comunicação e informação.

ECMAScript

Linguagem de programação padronizada pela especificação ECMA-262.

mocha / livescript (netscape 2.0)
jscript (MS Internet explorer 3.0)

  • 1996-1997: JAVASCRIPT (ES1)

  • 1998: ES2

  • 1999: ES3

  • 2000: WEB EVOLUTION
              
    ACTIONSCRIPT... (As2 / as3)

  • 2008: Es3.1 / eS4

  • 2009: ES5

  • 2010+ web (r)evolution

ES2015

  • novas especificações a cada ano (2016, 2017, 2018...)

  • MUITOS novos comandos e funcionalidades

  • sintaxe mais moderna e clean

  • ALGUMAS CORREÇÕES

  • RETROCOMPATIBILIDADE COM ES5

  • 2011  -  2015 (ES6)

LEANDRO NUNES

SENIOR software ENGINEER @ CI&T

TWITTER | GITHUB | hackerrank @LNFNUNES

let

"nova variável' / block scope

ES5

ES6

function js() {
  var version = 'ES5';

  if (true) {
    var version = 'ES2015';
    console.log('in', version);
  }

  console.log('out', version);
}

js();
// 'in ES2015'
// 'out ES2015'
function js() {
  let version = 'ES5';
  
  if (true) {
    let version = 'ES2015';
    console.log('in', version);
  }

  console.log('out', version);
}

js();
// 'in ES2015'
// 'out ES5'

ES6

let version = 'ES5';
{
  let version = 'ES2015';
  console.log('in', js);
}
let version = 'ES6'; // Uncaught SyntaxError
// Identifier 'js' has already been declared

ES5

ES6

for(var i = 1; i <= 5; i++) {
  $btn.onclick = function() {
    console.log('btn' + i);
  };
}
console.log(i); // 6

// 'btn 6'
// .
// .
// .
// 'btn 6'
for(let i = 1; i <= 5; i++) {
  $btn.onclick = function() {
    console.log('btn' + i);
  };
}
console.log(i);
// Uncaught ReferenceError:
// i is not defined


// 'btn 1'
// .
// .
// .
// 'btn 5'

const

imutável / block scope

ES6

const int = 1;
const arr = [1, 2, 3];
const obj = {x: 1};
const str = 'ES2015';

str = 'ES6'; // Uncaught TypeError:
// Assignment to constant variable.

const

imutável (?)

ES6

ES6

const obj = {x: 1};
obj.x = 2;
obj.y = 1;
console.log(obj);
// {x: 2, y: 1}

obj = {y: 1}; // Uncaught TypeError:
// Assignment to constant variable.



const arr = [1];
arr[0] = 2;
arr.push(2);
console.log(arr);
// [2, 2]

arr = [3]; // Uncaught TypeError:
// Assignment to constant variable.
const obj = Object.seal({x: 1});
obj.x = 2;
obj.y = 1;
console.log(obj);
// {x: 2}


const obj = Object.freeze({x: 1});
obj.x = 2;
obj.y = 1;
console.log(obj);
// {x: 1}

arrow function

syntactic SUGAR / "this" sem gambiarra

ES5

ES6

var sum = function(x, y) {
  return x + y;
}
console.log(sum(1, 2));
// 3
let sum = (x, y) => { return x + y; }
console.log(sum(1, 2));
// 3

let sum = (x, y) => x + y;
console.log(sum(1, 2));
// 3

let addOne = (x) => {
  console.log('Resultado');
  return x + 1;
};
console.log(addOne(2));
// Resultado
// 3

let addOne = x => x + 1;
console.log(addOne(2));
// 3

ES5

ES6

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  .filter(function(x) {
    return x % 2 === 0;
  })
  .filter(function(x) {
    return x > 6;
  })
  .reduce(function(x, y) {
    return x + y;
  })
);

// 18
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  .filter(x => x % 2 === 0)
  .filter(x => x > 6)
  .reduce((x, y) => x + y)

// 18

ES5

ES6

var name = 'Meetup';

function Meetup() {
  this.name = 'Front-end Campinas';
  setTimeout(function() {
    console.log(this.name);
  }, 10);
}
// Meetup

function Meetup() {
  var self = this;
  self.name = 'Front-end Campinas';
  setTimeout(function() {
    console.log(self.name);
  }, 10);
}
// Front-end Campinas

function Meetup() {
  this.name = 'Front-end Campinas';
  setTimeout(function() {
    console.log(this.name);
  }.bind(this), 10);
}
// Front-end Campinas
let name = 'Meetup';

function Meetup() {
  this.name = 'Front-end Campinas';
  setTimeout(() => console.log(this.name), 10);
}

new Meetup();
// Front-end Campinas

template literals

multiline / expression interpolation /

tagged template literals

ES5

ES6

var version = 5;
var html = '<h1>' +
 'ES' + version + ' é legal';
html += '</h1>';

console.log(html);
// <h1>ES5 é legal</h1>



console.log('ES' + 2000 + 15);
// 'ES200015'

console.log('ES' + (2000 + 15));
// 'ES2015'
const version = 2015;
let html = `
  <h1>
    ES${version} é MUITO legal
  </h1>`;

console.log(html);
// <h1>ES2015 é MUITO legal</h1>




console.log(`ES ${2000 + 15}`);
// 'ES2015'

ES6

function greet(raw, name) {
  let hello = 'Olá';
  if (raw[1] === ':en') {
    hello = 'Hello';
  }
  return `${hello} ${name}!`;
}

let name = 'Meetup';
console.log(greet`${name}`);
// Olá Meetup!
console.log(greet`${name}:en`);
// Hello Meetup!



// Evitar Script e XSS Injection
let url = '<script>alert("sexta-feira!")</script>';
console.log(safeUrl`[Sexta-Feira](${url})`);
// <a href="http://www.meetup.com">Sexta-feira</a>

default parameterS

SEM GAMBIARRA / SYNTACTIC SUGAR

ES5

ES6

function js(version) {
  version = version || 5;
  return 'ES' + version;
}

console.log(js());
// 'ES5'
function js(version = 2015) {
  return `ES${version}`;
}


console.log(js());
// 'ES2015'

console.log(js(6));
// 'ES6'

rest parameters

iterable object / SYNTACTIC SUGAR

ES5

ES6

function calc(x, y) {
  var rest = Array.prototype.slice
                  .call(arguments, 2);

  return (x + y) * rest.length;
}

console.log(calc(1, 2, 3, 4, 5));
// 9

function calc(x, y, ...rest) {
  return (x + y) * rest.length;
}

console.log(calc(1, 2, 3, 4, 5));
// 9

array

novos métodos
find / findindex / INCLUDES / fill / keys / entries...

destructuring

SYNTACTIC sugar

ES5

ES6

var objUser = {
  first:'Leandro',
  last:'Nunes'
};

var first = objUser.first;
var last = objUser.last;
console.log(first + ' ' + last);
// Leandro Nunes



var arr = [1, 2, 3];
var x = arr[0];
var z = arr[2];
console.log(x, z);
// 1 3
let objUser = {
  first:'Leandro',
  last:'Nunes'
};

let {first, last} = objUser;
console.log(`${first} ${last}`);
// Leandro Nunes

let {x:val1, y:val2} = {x:1, y:2};
console.log(val1, val2);
// 1 2

let [x, ,z] = [1, 2, 3];
console.log(x, z);
// 1 3

let [a, b] = [x, z];
console.log(a, b);
// 1 3

ES6

let objUser = {
  id: 1,
  first: 'Leandro',
  last: 'Nunes',
  city: 'Campinas'
};

function fullName({first, last = ''}) {
  return `${first} ${last}`;
}

console.log(fullName(objUser));
// Leandro Nunes

classes

ES6

ES6

class Evento {
  constructor(onde = 'SP') {
    this._onde = onde;
  }

  get onde() {
    return this._onde;
  }
  set onde(value) {
    this._onde = value;
  }

  marcaData(value) {
    this._quando = value;
  }
}

class Meetup extends Evento {
  constructor(onde) {
    super(onde);
  }
}
let evento = new Evento();
console.log(evento.onde);
// 'SP'

let meetup = new Meetup('Campinas');
meetup.onde = 'Campinas';
console.log(meetup.onde);
// 'Campinas'

modules

export / import

ES6

ES6

// module "meetup.js"

export function js() {
  return 'ROX';
}

const name = 'Front-end Meetup';
const version = '1.0';

export { name };

export default { version: version };
// app.js

import {js, name} from 'meetup';

import {name} from 'meetup';

import {js as javascript} from 'meetup';

import * as meetup from 'meetup';

import ver from 'meetup';
// alias
// import {default as ver} from 'meetup';

for...of

novo loop / iterable object

ES5

ES6

var arr = ['Meetup', 'Campinas', '2016'];
for(var k in arr) {
  console.log(k);
}
// 0
// 1
// 2



arr.forEach(function(item) {
  console.log(item);
})
// Meetup
// Campinas
// 2016
let arr = ['Meetup', 'Campinas', '2016'];
for(let k of arr) {
  console.log(k);
})
// meetup
// campinas
// 2016



let str = 'Meetup';
for(let k of str) {
  console.log(k); 
}
// M
// e
// e
// t
// u
// p

generator

SYNCHRONOUS

ES6

ES6

function* meetup() {
  console.log('inicio');
  yield 'Meetup';
  yield 'Front-end';
  yield 'Campinas';
  console.log('fim');
}

let gen = meetup();
console.log(gen.next());
// inicio
// {value: "Meetup", done: false}

console.log(gen.next());
// {value: "Front-end", done: false}

console.log(gen.next());
// {value: "Campinas", done: false}
// fim

console.log(gen.next());
// {value: undefined, done: true}
function* meetup() {
  console.log('inicio');
  yield* ['Meetup',
          'Front-end',
          'Campinas'];
  console.log('fim');
}

let gen = meetup();
for(let k of gen) {
  console.log(k);
};
// inicio
// Meetup
// Front-end
// Campinas
// fim

promise

aSYNCHRONOUS

callback hell

loginUser(function(err, response) {
  if (err) { throw 'Some error'; }

  getUserInfo(function(err, response) {
    if (err) { throw 'Some error'; }

    getUserPermissions(function(err, response) {
      if (err) { throw 'Some error'; }

      getUserPayments(function(err, response) {
        if (err) { throw 'Some error'; }

        getUserCourses(function(err, response) {
          if (err) { throw 'Some error'; }

          // DONE
          showPage();
        });
      });
    });
  });
});

promises

loginUser()
  .then(getUserInfo)
  .then(getUserPermissions)
  .then(getUserPayments)
  .then(getUserCourses)
  .then(showPage); // DONE
  .catch(err => {
    throw 'Some error';
  });

 jquery

 promise

function getJSON(url) {
  /*
    impl...
  */
}

$.getJSON('http://www.api.com/v1')
  .done(function(response) {
    console.log(response);
  })
  .fail(function(err) {
    console.log(err);
  });

console.log('Aguardando...')
// 'Aguardando...'
// 'ok'
function getJSON(url) {
  return new Promise((resolve, reject) => {
      setTimeout(() => resolve('ok'), 10);
    });
}

getJSON('http://www.api.com/v1')
  .then(response => console.log(response))
  .catch(err => console.log(err));

console.log('Aguardando...')
// 'Aguardando...'
// 'ok'

browsers support

es7
(ES2016)

  • Array.prototype.includes

  • Exponentiation Operator

 includes

 exponentiation

// Motivation...
if (arr.indexOf(el) !== -1)



// ES7...

[1, 2, 3].includes(2);
// true
[1, 2, 3].includes(4);
// false
['a', 'b', 'c'].includes('a');
// true
let squared = 2 ** 2;
// same as: 2 * 2
// 4

let cubed = 2 ** 3;
// same as: 2 * 2 * 2
// 8

let b = 3;
b **= 3;
// same as: b = b * b * b;
// 27

obrigado!

TWITTER | GITHUB @LNFNUNES

Made with Slides.com