From Tatooine

Ecmascript 6 — O velho novo Javascript

November 22, 2020 • 🤔 7 min read
Tags: javascript, es6

Em meados de 2015, foi lançada uma nova versão do Javascript, o ECMAScript 6 (ES6) ou ECMAScript 2015 (ES2015) com diversas funcionalidades que vieram para aumentar de forma exponencial a produtividade no desenvolvimento.

O ano de 2015 pode parecer longe no passado, quando falamos de tecnologia, mas ainda existe muito código legado de versões anteriores do Javascript por aí, então é um assunto que ainda vale muito a pena ser explorado.

São muitas novidades e para não se tornar uma leitura cansativa, vou focar nos pontos que mais trouxeram ganhos de produtividade e confiabilidade no código desenvolvido.

1. Variáveis e constantes

Nessa nova implementação, os conceitos de armazenamento de dados da aplicação respeitam o escopo onde elas são definidos. O uso do var para declaração de variáveis é desaconselhado, sendo substituido por let e const.

// formato não recomendado
var nomeAntigo = 'Lando';

// declarando uma constante
const nome = 'Han Solo';

// declarando uma variável
let anoNascimento = 1973;

// declarando uma variável dentro de um escopo de função
function calcularIdade(anoNascimento) {
    const anoAtual = 2020;
    
    return anoAtual - anoNascimento;
}

Não é possível alterar o valor de uma constante após o valor inicial definido, a tentativa retorna um erro (é possivel e não recomendado, alterar o valor de propriedades de um objeto definido com const).

2. Arrow functions

Uma grande vantagem da utilização de arrow functions é a redução de tamanho de código, principalmente quando executado em larga escala, com diversas funções encadeadas.

// declarando uma funcao antes do ES6
const calcularSoma = function (a, b) {
    return a + b;
};

// utilizando arrow function
const calcularSoma = (a, b) => {
    return a + b;
};

// forma resumida (return e chaves implícito)
const calcularSoma = (a, b) => a + b;

É importante deixar claro que a declaração de function não foi descontinuada ou desincentivada, as arrow functions vieram para complementar, com uma forma mais ágil de escrever.

3. Map, filter e reduce para arrays

Foram criadas 3 funções embutidas para facilitar o trabalho de operações em arrays, com 3 diferentes focos. Nos exemplos abaixo, vou citar com exemplos a funcionalidade de cada um.

Vamos usar o .map() para resgatar o ID de cada usuário de uma lista de usuários. Essa função vai percorrer cada item de um array e retornar exatamente o mesmo numero de elementos do array origem.

const usuarios = [
    { id: 10, name: 'Luke' },
    { id: 15, name: 'Leia' },
    { id: 20, name: 'Ackbar' },
];

const usuariosIds = usuarios.map(usuario => usuario.id);

// resultado será: [10, 15, 20]

Nesse próximo exemplo, vou utilizar .filter() para, veja bem… FILTRAR os elementos de uma lista. Essa função vai percorrer cada item de um array e retornar um novo array com os elementos filtrados do array original.

const usuarios = [
    { name: 'Luke', idade: 25 },
    { name: 'Leia', idade: 26 },
    { name: 'Ackbar', idade: 300},
];

const usuariosIds = usuarios.filter(usuario => usuario.idade > 30);

// resultado será: [{ name: 'Ackbar', idade: 300}]

E por fim, o .reduce(). Essa função vai percorrer cada elemento de um array para retornar um único valor decorrente de alguma operação em cada elemento.

const array = [1, 2, 3, 4];

const soma = array.reduce((total, elemento) => total + elemento);

// resultado será: 10

O argumento das funções .map(), .filter(), .reduce() é uma função.

4. Parâmetros padrão

Agora é possível definir um valor padrão para os argumentos de funções, o que pode facilitar o desenvolvimento em alguns casos.

// antes do ES6
function soma(a, b, c) {
    if (c == null) {
    c = 0;
    }

    return a + b + c;
}

// com ES6
function soma(a, b, c = 0) {
    return a + b + c;
}

5. Operador spread

O operador spread (…) nova funcionalidade no ES6 dá a possibilidade de realizar operações em arrays e objects sem necessidade de realizar uma iteração em cada um de seus valores.

// utilizando spread como argumento de uma função
function soma(...argumentos) {
    let total = 0;

    for (let i = 0; i < argumentos.length; i++) {
    total += argumentos[i];
    }

    return total;
}

soma(1, 2);
soma(1, 2, 3);

// utilizando spread para unir dois arrays
const lista1 = [1, 2, 3, 4];
const lista2 = [5, 6, 7, 8];

// listaResultado será: [1, 2, 3, 4, 5, 6, 7, 8];
const listaResultado = [...lista1, ...lista2];

// também é possível usar com objetos
const obj1 = {a: 1, b: 2};
const obj2 = {c: 3, d: 4};

// objResultado será:{a: 1, b: 2, c: 3, d: 4}
const objResultado = {...obj1, ...obj2};

6. Template string

Com a implementação do template string é possível definir valores de string concatenando variáveis e operações de forma simples e o código fica mais legível, além de ser muito mais rápido de escrever, visto que não é necessário se preocupar com os concatenadores (+).

const nome = 'Vader';
const anoNascimento = 1977;
const empresa = 'Death Star';

// antes do ES6
const frase = 'O ' + nome + ' tem ' + (2020 - anoNascimento) + ' e trabalha na empresa ' + empresa + '.';

// com ES6
const frase = `O ${nome} tem ${2020 - anoNascimento} e trabalha na empresa ${empresa}.`;

A template string suporta multi-line, ou seja, a string pode ter várias linhas sem necessidade de um caractere (+) no fim de cada linha informando a quebra.

7. Destructuring assignment

O recurso de destructuring agiliza a utilização de propriedades de objetos e valores de listas, como variáveis. Fica mais fácil de entender no exemplo abaixo:

const aluno = {
    nome: 'Padme',
    email: 'padme@secondtrilogy.com',
    idade: 23,
    cidade: 'Tikal',
};

// antes do ES6
var nome = aluno.nome;
var email = aluno.email;
var idade = aluno.idade;
var cidade = aluno.cidade;

// com ES6
const { nome, email, idade, cidade } = aluno;

Com a definição acima, as informações nome, email, idade, cidade podem ser usadas como variáveis no código a seguir.

8. Property Shorthand

Você pode agora inializar um objeto, sem precisar definir chave e valor para cada propriedade utilizando o property shorthand. Émais uma forma de agilizar e diminuir o tamanho do código. Vamos para o exemplo:

// antes do ES6
function cadastrarProfessor(nome, email, telefone) {
    var professor = {
        nome: nome,
        email: email,
        telefone: telefone,
    };

    cadastrar(professor);
};

// com ES6
function cadastrarProfessor(nome, email, telefone) {
    var professor = {
        nome,
        email,
        telefone,
    };

    cadastrar(professor);
};

A diferença do segundo para o primeiro caso é sutil, as propriedades do objeto professor podem omitir o valor, deixando apenas a chave.

PS.: As duas opções acima são válidas no ES6, a segunda é apenas uma alternativa de escrita.

9. Modules

Permite importar/exportar valores sem a necessidade de declaração deles em nível global dentro da aplicação.

Exemplo: nesse arquivo abaixo, operacoes.js, são declarados 2 funções e são exportadas para serem usadas em outros escopos.

function soma (a, b) {
    return a + b;
};

function multiplicacao (a, b) {
    return a * b;
};

export {
    soma,
    multiplicacao,
};

Essas funções podem ser chamadas em outros arquivos, como no exemplo abaixo do arquivo main.js.

import { soma } from './operacoes.js';

soma(3, 2);

10. Promises

Um dos principais motivos para criação das promises foi a necessidade de desenvolver um código mais limpo e organizado quando trabalhamos com operações assíncronas. Um famoso problema encontrado em muitos códigos javascript é o callback hell. As promises são uma proposta de resolução para esse problema.

No exemplo abaixo, vou efetuar uma requisição à API da minha aplicação para buscar os usuários cadastrados, dividindo a responsabilidade de um método exclusivo para o tratamento da requisição.

function getUsers() {
    return new Promise((resolve, reject) => {
    fetch('api/getUsers'/)
        .then(resposta => resolve(resposta.json())
        .catch(erro => reject(error);
    });
};

// utilizando a funcao acima
getUsers()
    .then(usuarios => console.log(usuarios))
    .catch(erro => console.log(erro.message));

Compatibilidade

A compatibilidade do ES6 com navegadores é bastante ampla e para os casos em que não é possível, a utilização de compiladores, como babel.js é recomendada. No link abaixo tem algumas informações sobre compatibilidade.

https://www.w3schools.com/js/js_versions.asp

Referência

Para construção desse artigo foram usadas informações disponibilizadas no site es6-features.org, que traz todas as novas funcionalidades implementadas no ES6.

Espero que essa leitura possa ter ajudado. 🚀

Até mais.