Novos recursos do JavaScript com o ES6 (ES2015)
ECMAScript 6(ES6) é a sexta versão padronizada do JavaScript, agora conhecida oficialmente como ECMAScript 2015 (ES2015), foi finalizada em Junho de 2015, foi o maior update do JavaScript, arrumando bugs da linguagem, trazendo novos recursos e algumas
novas sintaxes.
Hoje em dia já é utilizado por muitos projetos e é fundamental conhecer esses novos recursos do JavaScript.
Neste post irei comentar apenas alguns dos novos recursos, existem muito mais recursos :).
Irei comentar sobre seguintes
recursos:
- Escopo let/const
- Template Literals
- Parâmetros com valores padrões
- Parâmetros Rest
- Operador Spread
- Arrow Functions (( ) => { })
- Novos recursos para Objetos Literais
- Object Destructuring
- Array Destructuring
- Rest Item
- Parâmetros com 'Destructuring'
- Classes "Class"
- Módulos
Escopo let/const
Agora temos escopo por bloco, igual a algumas linguagens tipo o C, C#, Java etc..., para ter acesso a variáveis de escopo, precisamos utilizar ao invés de var
temos que utilizar a palavra reservada let
para variáveis e const
para constantes.
Variáveis ou constantes não podem ser declaradas mais de uma vez no mesmo escopo.
Exemplo:Mas este não causa erro:
Com escopo por bloco, agora podemos fazer coisas tipo isso:
Sem escopo por bloco temos que criar um escopo a cada iteração:
Outra característica é que let/const não poluem o objeto global (window no caso de browser) caso declarado num escopo global.
Template Literals
Nova maneira de criar strings e com novos recursos, como strings multiline e formatação por substituições de variáveis (Interpolação de Expressões).
Para criar esse tipo de string devemos utilizar o caracter `
(acento craseado).
Podemos ter quebras de linhas(multiline) sem a necessidade de concatenar.
Também podemos fazer substituições utilizando ${}
. Sendo que entre {} podemos ter qualquer variável ou expressão que retorne algum valor.
Tagged Template Literals
'Tagged template' é uma função que é executada na string "Template". Esta função recebe no primeiro parâmetro um array que é a string sem as substituições, sendo que cada posição do array é uma parte da string sem a substituição, o segundo parâmetro são
as substituições.O retorno da string será o retorno desta função. (Obs: o modo de chamar esta função é assim: funcTag`aaaaaaaaa`
, sem os parênteses mesmo)
Parâmetros com valores padrões
São valores que são atribuídos para os parâmetros que não são informados na chamada da função.
Exemplo:Parâmetros Rest
Um parâmetro Rest é indicado com 3 pontos (...) antes do nome do parâmetro. O parâmetro Rest é uma array contendo todos os valores restantes passados para a função.
Só deve existir apenas 1 parâmetro Rest numa função e este deve ser o último parâmetro.
Operador Spread
Operador Spread transforma um array em argumentos individuais numa chamada de função. São indicados também por 3 pontos (...) mas nas chamadas de função.
Exemplo:Arrow Functions (( ) => { })
Uma nova sintaxe de criar funções e com algumas caracteristicas:
- Não podem ser funções construtoras (não pode utilizar
new
para instanciação) - Não possuem
prototype
- O contexto (this) é do contexto da função (não arrow) mais próxima (a função pai)
- Não possuem o objeto
arguments
- Seu contexto não pode ser alterado por call(), apply(), ou bind()
A sintaxe da Arrow function é a seguinte:
(parâmetros) => {corpo da função}
Outra caracterisca da arrow function é quando a função de apenas uma instrução retorna um objeto literal, neste caso devemos envolver o corpo da funcão entre parênteses.
Outros exemplos de arrow function:
Novos recursos para Objetos Literais
-
Inicializador de propriedades: é uma maneira curta de atribuir valores para propriedades de um objeto. para variaveis que possuem o mesmo nome da propriedade
Exemplo: -
Criar método:
Novo modo de criar métodos em objetos literais, eliminando
Exemplo:':'
e a palavra'function'
. -
Nome de propriedades computadas( definidas com o resultado de uma expressão) Agora podemos definir uma propriedade dinamicamente, para isso é necessário usar
Exemplo:[(expressão)] : valor
sendo que a expressão pode ser qualquer variavel ou expressão que retorne algum valor que será o nome da propriedade.
Object Destructuring
É uma maneira mais simples e econômica de criar variáveis com valores das propriedades de um objeto.
Exemplo:Array Destructuring
Possui a mesma idéia do Object Destructuring, mas com Arrays, ou seja você cria variavés extraindo valores de um Array. Ao invés de nomes de propriedades ele utiliza a posição do item do Array para atribuir valor a variável.
Exemplo:Rest Item
No contexto de atribuição 'Destructuring' utiliza-se Rest Item para atribuir os valores restantes do array para uma variável. É indicado também usando 3 pontos (...), mas na atribuição.
Exemplo:Parâmetros com 'Destructuring'
Podemos usar toda a ideia de 'Destructuring' nos parâmetros de uma função.
Classes "Class"
Agora temos uma nova sintaxe para criar "classes", mas internamente ainda é tudo baseado em prototype
. Para cria função construtora ("classe"), utilizamos a palavra reservada class
.
Seria basicamente o mesmo que:
Algumas características das classes criadas com class
:
- Não podemos criar propriedades no corpo da 'class'. Para criar propriedades devemos usar o construtor ou via métodos set/get.
- Não sofrem 'hoisting' pela engine Javascript, diferente das funções que sofrem 'hoisting'.
-
Executam em modo
strict
. -
Só podem ser chamadas com
new
. -
Os métodos não devem ser chamados com
new
, e eles não sãoenumerable
(não vão aparecer no Object.keys por exemplo). - O nome da classe não pode ser sobrescrito dentro dos métodos
Se fosse criar uma classe sem class
seguindo estas caracteristicas poderíamos fazer o seguinte:
Herança "extends"
No JavaScript a 'Herança' ocorre por prototype, existem algumas maneiras de fazer isso, uma delas é a seguinte:
Agora com o ECMAScript 6 foi adicionada a palavra reservada extends
para realizar herança de uma maneira mais simples.
Também criada a palavra super
para acessar a classe base
Veja como ficaria o exemplo anterior:
Algumas considerações:
- No construtor, o
super
deve ser chamado antes de qualquer acesso àthis
- Caso a classe que está realizando extends não defina o
constructor
ele será definido e chamado implicitamente passando todos os parâmetros. - Podemos sobrescrever um método com mesmo nome da classe base, e também podemos ter acesso ao método base usando o
super
, por exemplosuper.getNome()
Métodos estáticos
Para criar um método estático utilizamos a palavra static
antes do nome do método.
Obs:Classes que usam herança também herdam os métodos estáticos da classe base.
Módulos
Enfim agora temos oficialmente um sistema de módulos no JavaScript, por muitos anos os desenvolvedores veêm utilizando módulos AMD, CommonJS, UMD, e etc... atráves de algumas ferramentas como require.js, webpack, browserify etc... ou no Node nativamente com padrão CommonJS . Mas agora temos um padrão oficial de módulos na linguagem.
O que são Módulos?
Um módulo é um arquivo JavaScript "isolado"(as váriaveis declaradas só ficam visíveis dentro do módulo) que podemos exportar alguma função, variável, ou objeto. Para exportar utilizamos a palavra export
e para que podemos acessar algum
recurso de algum módulo devemos importar-lo utilizando a palavra import
.
Export
Em um módulo podemos exportar mais de uma variável, veja alguns exemplos:
Import
Para utilizar um módulo devemos importá-lo, podemos importar de várias formas, sendo que a sintaxe básica de importar é a seguinte:
import { algumIdentificador } from 'caminho-do-modulo'
Entre {}
colocamos os nomes das variáveis(identificadores) que vamos 'importar' do módulo, no from
devemos especificar o caminho do módulo, sendo
que nos browsers o "caminho-do-modulo" deve ter a extensão '.js'. Para modulos que são exportados com 'default' não precisamos de {}
.
Veja os exemplos:
Obs: o módulo é executado apenas no primeiro import, mesmo se você tiver outro import ele não irá executar o módulo, pois ele utilizará a referência do modulo que já estará em memória.
import/export módulos default
Podemos utilizar a palavra default
para exportar apenas uma variável que pode ser anônima, o módulo só pode ter apenas um default
, por exemplo:
Para importar algum modulo default, devemos fazer o seguinte:
Já podemos usar ECMAScript 6 ?
Sim, já podemos utilizar, veja a tabela abaixo que mostra percentual de recursos do ES6 que já foram implementados em cada ambiente:
Para dar suporte a ambientes antigos podemos utilizar um transpiler que transforma nosso código ES6 para ES5. O Babel é a ferramenta adequada para fazer isso. Podemos usá-lo com o gulp, webpack etc...
Acesse http://babeljs.io/repl/ e escreva algum código ES6 para ver como fica o código compilado para ES5.
Conclusão
O ES6 foi realmente o maior update do JavaScript, trazendo muitas facilidades e mais poder para a linguagem, sem dúvida nenhuma foi uma grande melhoria, mas não para ai, agora todo ano terá uma nova especificação para o ECMAScript, lógico que não tão
grande igual a ES6. Já temos a ES7(ES 2016) e a ES8(ES2017) por exemplo.