ES6 – Consertando as partes ruins do JavaScript



ES6 – Consertando as partes ruins do JavaScript

0 0


jsday

JSDay talk about ES6

On Github diofeher / jsday

ES6

Consertando as partes ruins do JavaScript

Diógenes Fernandes / @diofeher / Software Engineer at Robots + Rockets

Implementação da linguagem

Brendan Eich - Netscape em Abril de 1995

10 dias para criar um protótipo de linguagem leve

Java vs Javascript: primos?

If I had done classes in JavaScript back in May 1995, I would have been told that it was too much like Java or that JavaScript was competing with Java … I was under marketing orders to make it look like Java but not make it too big for its britches … [it] needed to be a silly little brother language.

Brendan Eich

ECMA

European Computer Manufacturers Association

ECMAScript

1997: Primeira versão ECMA-262

ES6 ou ECMAScript 2015

Especificação finalizada em Junho/2015

Implementação em andamento

https://kangax.github.io/compat-table/es6/

1. Block Scoping

Hoisting

x = 5; // Assign 5 to x

elem = document.getElementById("demo"); // Find an element 
elem.innerHTML = x;                     // Display x in the element
var x; // Declare x

Problemas com Hoisting

// var i;
var anchors = document.getElementsByTagName(“a”);
for(var i=0, len=anchors.length; i < len; i++) {
    anchors[i].onclick = function(){
        alert(i);  // alert 10 ten times
    };
}

Usando IIFE para resolver o problema

var anchors = document.getElementsByTagName(“a”);
for(var i=0, len=anchors.length; i < len; i++) {
    anchors[i].onclick = (function(i){
        return function() {
            alert(i);  // 1, 2, 3...
        }
    })(i);
}

Código ruim de ler e estranho para pessoas novas na linguagem

Block scoping usando let

var anchors = document.getElementsByTagName(“a”);
for(let i=0,len=anchors.length; i < len; i++){
    anchors[i].onclick = function(){
        alert(i);
    }
}

const para variáveis read-only

const API_KEY = '123lkdsfj43ojisKOD21a';
const CONFIG = {
    TEMPLATES_URL: '/templates',
    TIMEZONE:  'America/Recife'
}
CONFIG['TEMPLATES_URL'] = 'http://s3.amazon.com/templates-folder';

Global binding

// in a browser
let RegExp = "Hello!";
console.log(RegExp);                    // "Hello!"
console.log(window.RegExp === RegExp);  // false

const ncz = "Hi!";
console.log(ncz);                       // "Hi!"
console.log("ncz" in window);           // false

2. Strings

Multi-linha

var test = "Aqui temos uma\n" +
"string que \n" +
"tem várias linhas."

Template Strings

`String`

Novas Multi-linha

let test = `Aqui podemos 
escrever utilizando uma nova linha
e o JS irá reconhecer.`

let message = `WhiteSpace
               string`;

Interpolação de strings (ES5)

// Usando o operador +
var name = 'Tyler Durden';
var phrase = 'As coisas que você possui acabam possuindo você.';
var say = '"'+ phrase +'" por ' + name;
console.log(say); // "As coisas que você possui acabam 
// possuindo você." por Tyler Durden

Interpolação de strings (ES6)

// Usando o operador +
var name = 'Tyler Durden';
var phrase = 'As coisas que você possui acabam possuindo você.';
var say = `"${phrase}" por ${name}`;
console.log(say); // "As coisas que você possui acabam
// possuindo você." por Tyler Durden

Interpolação usando expressões

let count = 10,
    price = 0.25,
    message = `${count} items cost $${(count * price).toFixed(2)}.`;

3. Desestruturação

Desestruturação (ES5)

var data = {
    "url": "http://twitter.com/api/",
    "username": "diofeher",
    "password": "javascript"
};

function apiRequest(data) {
    var url = data.url,
        username = data.username,
        password = data.password;
    if(!url) {
        url = "http://instagram.com/api/";
    }
    $.post(url, username, password);
};
apiRequest(data);

Desestruturação (ES6)

var data = {
    "url": "http://twitter.com/api/",
    "username": "diofeher",
    "password": "javascript"
};

function apiRequest(data) {
    var { url, username, password } = data;
    if(!url) {
        url = "http://instagram.com/api/";
    }
    $.post(url, username, password);
};
apiRequest(data);

4. Funções

Definição de funções (ES5)

var reflect = function(value) {
    return value;
};

() =>

Arrow functions sem parâmetros (ES6)

var getName = () => "Javascript";

// effectively equivalent to:

var getName = function() {
    return "Javascript";
};

Arrow functions (ES6)

var reflect = value => value;

Arrow functions com parâmetros (ES6)

var sum = (num1, num2) => num1 + num2;

// effectively equivalent to:

var sum = function(num1, num2) {
    return num1 + num2;
};

Arrow functions - this (ES5/6)

var test = function() {
    that = this;
    var doSomething = function() {};
    document.addEventListener("click", function(event) {
        this.doSomething(event.type); // certo é that
    });
}

document.addEventListener("click", function() {
    event => this.doSomething(event.type));

Argumentos default (ES5)

var myFunction = function(a, b, c){
    a = a || 10;
    b = b || 5;
    c = c || 8;
    return a * b * c;
};

Problema: Se o argumento for 0 ou string vazia

Argumentos default melhorados (ES5)

var myFunction = function(a, b, c){
    a = (typeof a !== "undefined") ? a : 10;
    b = (typeof b !== "undefined") ? b : 5;
    c = (typeof c !== "undefined") ? c : 8;
    return a * b * c;
};

Argumentos default (ES6)

var myFunction = function(a=10, b=5, c=8){
    return a * b * c;
};

Parâmetros sem nome (ES5)

function pick(object) {
    let result = Object.create(null);
    for (let i = 1, len = arguments.length; i < len; i++) {
        result[arguments[i]] = object[arguments[i]];
    }
    return result;
}

let book = {
    title: "Understanding ECMAScript 6",
    author: "Nicholas C. Zakas",
    year: 2015
};
let bookData = pick(book, "author", "year");
console.log(bookData.author);   // "Nicholas C. Zakas"
console.log(bookData.year);     // 2015

Parâmetros Rest (ES6)

function pick(object, ...keys) {
    let result = Object.create(null);

    for (let i = 0, len = keys.length; i < len; i++) {
        result[keys[i]] = object[keys[i]];
    }

    return result;
}

Passando array como argumento (ES5)

let values = [25, 50, 75, 100]

console.log(Math.max.apply(Math, values));  // 100

Passando array como argumento (ES6)

let values = [25, 50, 75, 100]

console.log(Math.max(...values));  // 100

5. Objetos

Inicialização de objetos (ES5)

function createPerson(name, age) {
    return {
        name: name,
        age: age
    };
}

Inicialização de objetos (ES6)

function createPerson(name, age) {
    return {
        name,
        age
    };
}

Definição de métodos (ES5)

var language = {
    name: "Javascript",
    sayName: function() {
        console.log(this.name);
    }
};

Definição de métodos (ES6)

var language = {
    name: "Javascript",
    sayName() {
        console.log(this.name);
    }
};

Comparação de Objetos (ES5)

“7” == 7  // true
“7” === 7 // false

Comparação de Objetos (ES5)

NaN == NaN  // false
NaN === NaN  // false
var result = isNan(NaN) // true

Object.is to the rescue!

Object.is(7, ”7”) // false
Object.is(7, 7) // true
Object.is(NaN, NaN) // true

6. Classes

Classes (ES5)

function PersonType(name) {
    this.name = name;
}

PersonType.prototype.sayName = function() {
    console.log(this.name);
};

let person = new PersonType("Diogenes");
person.sayName();   // outputs "Diogenes"

Classes (ES6)

class PersonClass {

    // equivalent of the PersonType constructor
    constructor(name) {
        this.name = name;
    }

    // equivalent of PersonType.prototype.sayName
    sayName() {
        console.log(this.name);
    }
}

let person = new PersonType("Diogenes");
person.sayName();   // outputs "Diogenes"

Se são parecidos, porque usar?

  • Não são hoisted
  • Não podem ser criadas sem o new

First-class Citizens

function createObject(classDef) {
    return new classDef();
}

let obj = createObject(class {

    sayHi() {
        console.log("Hi!");
    }
});

obj.sayHi();        // "Hi!"

Gets e Sets

class Element {
    constructor(element) {
        this.element = element;
    }
    get val() {
        return this.element;
    }
    set val(value) {
        this.element = value;
    }
}
test = new Element("test")
console.log(a.val) // "test"
a.element = 3;
console.log(a.val) // 3

Super keyword (ES5)

var myBaseObj = {
    sayName: function(){
        // .. do something
    };
};

var mySubObj = Framework.extend(myBaseObj, {
    sayName: function(){
        this._super.apply(this, arguments);
        // .. do something else
    }
})

Super keyword (ES6)

var myBaseObj = {
    sayName: function(){
        // .. do something
    };
};
var mySubObj = {
    __proto__: myBaseObj,
    sayName: function(){
        super.sayName();
        // .. do something else
    }
})

ES6: Muito mais!

  • Promises
  • Iterators
  • Generators
  • Symbols
  • Sets e Maps
  • Modules

...

ES6 Consertando as partes ruins do JavaScript Diógenes Fernandes / @diofeher / Software Engineer at Robots + Rockets