Classes ES6: fabricando objetos em série
Quando muitos objetos precisam nascer com a mesma forma e o mesmo comportamento, copiar e colar cada um na mão não escala. As classes existem para fabricar objetos em série, com uma única receita.
Estudar esta lição interativa →Imagine um jogo com dezenas de inimigos, ou uma loja com centenas de produtos: cada um precisa nascer com a mesma forma (os mesmos campos: nome, vida, preço) e o mesmo comportamento (os mesmos métodos: atacar, aplicarDesconto). Criar cada objeto manualmente, copiando e colando o objeto literal, funciona para dois ou três, mas desmorona rápido: qualquer ajuste no comportamento exigiria editar todos, um por um, e é fácil esquecer algum. A classe resolve isso: ela é uma receita única para fabricar objetos daquele "tipo", em série.
A palavra class cria essa receita. Dentro dela, o constructor é uma função especial que roda automaticamente toda vez que um objeto novo nasce, e é ali que você define os campos iniciais (usando this, exatamente o this que você aprendeu no módulo passado, aqui apontando sempre para o objeto recém-criado). Os métodos, por sua vez, são compartilhados por todas as instâncias, é o mesmo mecanismo de protótipo da lição anterior, só que a sintaxe de classe cuida disso por você:
class Usuario {
constructor(nome, idade) {
this.nome = nome;
this.idade = idade;
}
saudacao() {
return "Olá, eu sou " + this.nome + " e tenho " + this.idade + " anos.";
}
}
const ana = new Usuario("Ana", 28);
const bia = new Usuario("Bia", 34);
console.log(ana.saudacao());
console.log(bia.saudacao());
// Os dois usam o MESMO método saudacao (compartilhado via protótipo),
// mas cada um tem seus próprios dados (nome, idade).Pense na classe como um molde de biscoito. O molde (a class) define o formato: toda massa que passa por ele sai com a mesma silhueta (os mesmos campos e métodos). Cada biscoito que sai do molde é uma instância, criada com new: parecidos na forma, mas cada um é um biscoito diferente, com o seu próprio recheio (os valores específicos daquela instância, como o nome ou o preço de aquele produto).
Classes também sabem herdar comportamento de outras classes, com a palavra extends. Isso evita reescrever o que já existe: uma classe mais específica herda tudo da mais geral e só acrescenta (ou ajusta) o que for diferente. Dentro do constructor de uma subclasse, a primeira coisa a fazer, sempre, é chamar super(...), que executa o constructor da classe "mãe" antes de qualquer outra coisa:
class Usuario {
constructor(nome) {
this.nome = nome;
}
saudacao() {
return "Olá, eu sou " + this.nome;
}
}
class Administrador extends Usuario {
constructor(nome, nivel) {
super(nome); // roda o constructor de Usuario primeiro, sempre
this.nivel = nivel;
}
saudacao() {
// reaproveita o método da classe mãe e acrescenta algo:
return super.saudacao() + " (admin nível " + this.nivel + ")";
}
}
const admin = new Administrador("Lucas", 3);
console.log(admin.saudacao());
console.log(admin instanceof Usuario); // true: Administrador É um UsuarioO primeiro: esquecer o new ao criar uma instância (escrever Usuario("Ana", 20) em vez de new Usuario("Ana", 20)) faz o JavaScript recusar a chamada com um erro, já que classes exigem new por segurança. O segundo, específico de herança: usar this dentro do constructor de uma subclasse antes de chamar super() também dá erro, porque o objeto só fica pronto para uso depois que a classe mãe terminou de montá-lo. A regra é simples: super() sempre na primeira linha do constructor de quem usa extends.
Modelar as entidades de um app real (Usuário, Produto, Pedido, Personagem) com classes é extremamente comum, especialmente quando existem várias instâncias parecidas e alguma hierarquia natural entre elas, como um AdministradorDaLoja que é um Usuario com poderes extras. É exatamente o padrão do exemplo acima.
// Sua vez! Complete a classe Produto.
class Produto {
constructor(nome, preco) {
// guarde os dois campos em this
}
descricao() {
// devolva algo como "Caderno - R$ 12"
}
}
const p1 = new Produto("Caderno", 12);
console.log(p1.descricao());Complete a classe Produto e clique em Rodar.