Classes em ECMAScript 6
Com a nova versão do ECMAScript (6) finalizada em junho … é hora de fixar algo das novidades :D. Segue um apanhado que fiz (fontes abaixo) para entender melhor as peculiaridades das classes na nova encarnação do ECMAScript.
Classes no ES6 são apenas um açucar sintático sobre o padrão de OO baseado em protótipos do JavaScript de sempre e não um novo modelo de OO para a linguagem.
De qualquer maneira, essa nova forma é muito mais simples de usar e portanto encoraja o uso de OO. Vejamos a aparência de uma classe ES6:
1 | class Point { |
As classes no ES6, entretanto, não suportam ainda alguns features importantes. Vejamos rapidamente seus recursos e omissões.
Classes ES6 suportam:
- construtor: método especial para criar e inicializar instâncias da classe.
- métodos de instância
- métodos estáticos: a keyword
static
define um método para a classe. Métodos estáticos são chamados diretamente pela classe (não pelas instâncias) e são normalmente usados para criar funções utilitárias relativas à instâncias da classe. - getters: métodos que permitem vincular uma “propriedade” da instância para uma função cujo retorno é oferecido sempre que a “propriedade” é acessada (ou seja, a propriedade retorna um valor dinamicamente computado).
- setters: métodos que permitem vincular uma “propriedade” da instância para uma função que é invocada quando tentamos atribuir algo para a “propriedade” (podemos criar um par de setter/getter com o mesmo nome, simulando uma propriedade normal)
- sub-classing: subclasses podem ser facilmente criadas usando a keyword
extends
. - super calls: a keyword
super
pode ser usada para invocar métodos da classe pai.
Classes ES6 não suportam:
- inicializadores de propriedade: a sintaxe de definição de classe suporta apenas métodos (constructor, métodos estáticos e métodos da instância) e não propriedades, portanto não podemos utilizar
foo = "bar";
oufoo : "bar";
dentro da definição da classe. Propriedades das instâncias, portanto, são normalmente definidas no constructor enquanto propriedades da classe são atribuídas após a definição da classe (var classe = class { }; classe.propDaClasse = "string"
).
- inicializadores de propriedade: a sintaxe de definição de classe suporta apenas métodos (constructor, métodos estáticos e métodos da instância) e não propriedades, portanto não podemos utilizar
A ausência de inicializadores de propriedade está sendo debatida atualmente na comunidade JS e as próximas versões do ES devem suprir essa carência.
Outras características de classes que considero importantes:
- O escopo dos métodos da classe é dinâmico e não léxico. Significando que se passarmos o método como uma callback para outro escopo, o
this
obedecerá o comportamento normal de fn()s JavaScript e dependerá da forma como a função for invocada. Se quisermos que as funções que representam os métodos de instância sempre tenham a instância comothis
, podemos fazer:
1 | class Counter { |
- O resultado da definição de uma classe é apenas uma função:
1 | typeof Point |
- Apenas podemos instanciar uma classe usando
new
, não é possível fazer isso invocando a classe:
1 | Point() |
Links
- Classes in ECMAScript 6 (final semantics): Excelente material sobre classes ES6, abordando semântica, etc.
- Classes - JavaScript | MDN: Documentação da Mozilla sobre classes.
- Learn ES2015 · Babel - Classes: Trecho sobre classes de um apanhadão sucinto das novidades do ES6.
- ES6 In Depth: Classes ✩ Mozilla Hacks – the Web developer blog: Artigo abordando detalhes do tema e incluindo algumas limitações atuais.
- getter - JavaScript | MDN: Documentação da Mozilla sobre getters.
- setter - JavaScript | MDN: Documentação da Mozilla sobre setters.
- this - JavaScript | MDN: Documentação da Mozilla sobre
this
. - Autobinding, React and ES6 Classes e React v0.13.0 Beta 1 | React: Links interessantes sobre a adoção pelo React das classes ES6 e das consequências de sua limitação.