Aprenda / JavaScript do zero

IntermediárioAula 11 de 1616 min0% da trilha

Prototypes e classes ES6

class parece Java ou C#, mas por baixo é o mesmo mecanismo de protótipo que sempre existiu em JavaScript.

JavaScript não tem herança por classe "de verdade" como Java ou C# — o que existe por baixo é herança prototípica. class é uma forma mais legível de escrever a mesma coisa, não um mecanismo novo.

Todo objeto tem um protótipo

Quando você acessa uma propriedade que um objeto não tem diretamente, o motor de JavaScript procura no protótipo desse objeto — um outro objeto ligado a ele por baixo dos panos.

const animal = {
  emitirSom() {
    console.log("Algum som genérico");
  },
};

const cachorro = Object.create(animal); // cachorro nasce com "animal" como seu protótipo
cachorro.emitirSom(); // "Algum som genérico" — cachorro não tem esse método, mas encontra no protótipo

Object.getPrototypeOf(cachorro) === animal; // true

A forma antiga: função construtora + prototype

Antes do class existir (ES6, 2015), esse mesmo padrão era escrito com função construtora e o objeto .prototype dela:

function Animal(nome) {
  this.nome = nome;
}
Animal.prototype.emitirSom = function () {
  console.log(`${this.nome} faz um som`);
};

const rex = new Animal("Rex");
rex.emitirSom(); // "Rex faz um som" — o método está em Animal.prototype, não em rex diretamente
rex.hasOwnProperty("emitirSom"); // false — confirma que veio do protótipo, não do próprio rex

class, extends e super

class Animal {
  constructor(nome) {
    this.nome = nome;
  }
  emitirSom() {
    console.log(`${this.nome} faz um som`);
  }
}

class Cachorro extends Animal {
  emitirSom() {
    super.emitirSom(); // chama a versão de Animal antes de continuar
    console.log(`${this.nome} late: Au au!`);
  }
}

const rex = new Cachorro("Rex");
rex.emitirSom();
// "Rex faz um som"
// "Rex late: Au au!"

extends monta a cadeia de protótipos pra você; super chama o construtor ou método da classe pai a partir da classe filha.

Por que class é "açúcar sintático"

Nenhum mecanismo novo foi criado no ES6 — class só organiza o mesmo padrão de função construtora + prototype numa sintaxe mais parecida com outras linguagens.

typeof Animal; // "function" — por baixo, uma class é uma função especial

Object.getPrototypeOf(rex) === Cachorro.prototype;             // true
Object.getPrototypeOf(Cachorro.prototype) === Animal.prototype; // true — a cadeia que extends monta

Exercício

Crie uma classe Veiculo com constructor(marca) e um método descrever() que retorna "Veículo da marca X". Depois crie Carro extends Veiculo que sobrescreve descrever() chamando super.descrever() e completando com ", tipo carro".

Quiz rápido

Por que dizemos que class é 'açúcar sintático' em JavaScript?
O que Object.create(animal) faz ao criar cachorro?