Classes e objetos em JavaScript: introdução à POO (ES6)

Classes e objetos em JavaScript: introdução à POO (ES6)

No capítulo anterior vimos como trabalhar com os eventos em JavaScript. Neste capítulo vamos interessar-nos pelas classes e pelos objetos.

Vale a pena perceber as classes e os objetos em JavaScript, porque permitem criar estruturas de dados mais complexas e organizar melhor o código. Antes de avançares para as classes e os objetos, convém conhecer as bases da programação orientada a objetos.

O que é uma classe em JavaScript?

Uma classe é um molde que serve para criar objetos. Define as propriedades e os métodos que esses objetos vão ter. Com classes podes criar vários objetos que partilham as mesmas propriedades e os mesmos métodos, o que é muito prático em imensos casos.

Declarar uma classe

Para criar uma classe em JavaScript podes usar a sintaxe seguinte:

javascript
class MaClasse {
  // Construtor da classe
  constructor() {
    // Inicialização das propriedades e dos métodos da classe
  }

// Métodos da classe
  maMethode() {
    // Código do método
  }
}

Construtor e métodos de uma classe

A definição de uma classe em JavaScript inclui o seu construtor, um método especial que serve para criar e inicializar um objeto a partir dessa classe.

O construtor de uma classe define-se com a palavra-chave «constructor». Por exemplo:

javascript
// Construtor da classe
constructor() {
// Inicialização das propriedades e dos métodos da classe
}

Os métodos de uma classe definem-se tal como as funções, com a diferença de que não se usa a palavra-chave «function».

javascript
// Métodos da classe
maMethode() {
 // Código do método
}

Aos métodos de um objeto acedes da mesma maneira que às propriedades, com esta sintaxe: monObjet.maMethode();

javascript
const monObjet = new MaClasse();
monObjet.maMethode();

Herança com as classes

A herança é um conceito central da programação orientada a objetos (POO). Consiste em criar uma nova classe a partir de uma classe existente, herdando dela as propriedades e os métodos. Isso permite reutilizar código e organizar melhor a aplicação.

Em JavaScript, a herança entre classes faz-se com a sintaxe «extends». Eis um exemplo de uma classe «Enfant» que herda de uma classe «Parent»:

javascript
class Parent {
  constructor(nom) {
    this.nom = nom;
  }

saluer() {
    console.log(Bonjour, je suis ${this.nom});
  }
}

class Enfant extends Parent {
  constructor(nom, age) {
    super(nom);
    this.age = age;
  }
}

const enfant1 = new Enfant('Marie', 7);
enfant1.saluer(); // Bonjour, je suis Marie

Utilizar o método super

O método super serve para chamar um método da classe-mãe a partir de uma classe-filha. Por exemplo, se tens uma classe Animal com um método «move()» que define como os animais se deslocam, e tens uma classe Chat que herda da classe Animal, podes usar o método super para chamar o método «move()» da classe Animal a partir da classe Chat. Eis um exemplo de código:

javascript
class Animal {
  move() {
    console.log('Je me déplace');
  }
}

class Chat extends Animal {
  move() {
    console.log('Je me déplace en sautant');
    super.move();
  }
}

const monChat = new Chat();
monChat.move();
// mostra "Je me déplace en sautant" e depois "Je me déplace"

Métodos estáticos

Os métodos estáticos pertencem à própria classe e não às suas instâncias. Podem ser chamados sem instanciar a classe. Por exemplo, podes definir um método estático «getAnimalType()» na classe Animal que devolve o tipo de animal. Eis um exemplo de código:

javascript
class Animal {
  static getAnimalType() {
    return 'Animal';
  }
}

console.log(Animal.getAnimalType()); // mostra 'Animal'

Os métodos estáticos não podem ser chamados sobre instâncias da classe. Se tentares chamar o método «getAnimalType()» numa instância da classe Animal, vais obter um erro.

Como manipular as propriedades do nosso objeto?

Também podes passar parâmetros ao construtor da classe para inicializar as propriedades do objeto:

javascript
class MaClasse {
  constructor(param1, param2) {
    this.param1 = param1;
    this.param2 = param2;
  }
}
const monObjet = new MaClasse("Valeur de param1", "Valeur de param2");

Para aceder a uma propriedade de um objeto, podes usar a sintaxe seguinte:

javascript
monObjet.maPropriete;

Para alterar uma propriedade de um objeto, podes usar a sintaxe seguinte:

javascript
monObjet.maPropriete = "Nouvelle valeur";

Para apagar uma propriedade de um objeto, podes usar o operador «delete» assim:

javascript
delete monObjet.maPropriete;

Não podes apagar uma propriedade de um objeto se ela estiver definida no protótipo do objeto. Para saber como lidar com as propriedades herdadas, consulta a secção seguinte sobre a herança com objetos.

Acrescentar getters e setters à nossa classe

Os getters e os setters são métodos que permitem ler e alterar as propriedades de um objeto de forma controlada. Usam-se sobretudo quando queres acrescentar uma lógica específica no momento em que uma propriedade é lida ou modificada.

Eis um exemplo de utilização de getters e setters numa classe:

javascript
class MonObjet {
  constructor(propriete) {
    this._propriete = propriete;
  }

// Getter
  get propriete() {
    return this._propriete;
  }

// Setter
  set propriete(value) {
    this._propriete = value;
  }
}

const objet = new MonObjet('valeur initiale');
console.log(objet.propriete); // mostra 'valeur initiale'

objet.propriete = 'nouvelle valeur';
console.log(objet.propriete); // mostra 'nouvelle valeur'

Os getters e setters são métodos, não propriedades. Por isso tens de usar a sintaxe objet.propriete() para aceder ao seu valor, e não objet.propriete (sem parênteses).

No exemplo acima, usámos um getter para ler o valor da propriedade _propriete e um setter para a alterar. Definimos também a propriedade _propriete com a palavra-chave this no construtor da classe. Essa propriedade é privada e só pode ser alterada através dos getters e setters.

Recomendação

Convém usar getters e setters quando queres executar operações adicionais ao ler ou ao alterar o valor de uma propriedade. Por exemplo, podes usar um setter para verificar que o valor recebido é válido antes de o atribuir à propriedade. Eis um exemplo de utilização de getters e setters numa classe:

javascript
class MonObjet {
  constructor(valeur) {
    this._maPropriete = valeur;
  }

get maPropriete() {
    return this._maPropriete;
  }

set maPropriete(valeur) {
    if (typeof valeur === 'string') {
      this._maPropriete = valeur;
    } else {
      console.log('La valeur doit être une chaîne de caractères');
    }
  }
}

const monObj = new MonObjet('ma valeur');
console.log(monObj.maPropriete); // Mostra 'ma valeur'
monObj.maPropriete = 42; // Mostra 'La valeur

Conclusão

Vimos como usar as classes e os objetos em JavaScript para estruturar e organizar melhor o código, e depois como criar e manipular objetos a partir de classes com o construtor e os métodos. Também abordámos a herança entre classes com o método super e os métodos estáticos. Por fim, falámos dos getters e setters, que permitem controlar o acesso às propriedades de um objeto e a sua modificação.

No capítulo seguinte vamos ver como tratar os erros e depurar o código com o try-catch e as ferramentas de depuração do navegador. Isso vai ajudar-nos a perceber melhor o que se passa no código e a corrigi-lo quando for preciso.

JavaScript

Damien Flandrin Programador web desde 2010, criador da Gekkode e do Email Impact. Cada artigo é testado num projeto real antes de ser publicado. Contacto
Newsletter

Os novos testes, tutoriais e projetos, por e-mail.

Testes reproduzíveis, código versionado, resultados datados. Nunca spam.