Classes vs Funções Construtoras vs Funções Fábrica

[ Prós e Contras ]

Classe

É uma função construtora. Ou seja, uma estrutura que descreve estados e comportamentos de um objeto.

Foram introduzidas no ECMAScript 6 e são simplificações da linguagem para as heranças baseadas nos protótipos. Mas preste atenção:

JavaScript não possui classes!

A sintaxe para classes não introduz um novo modelo de herança de orientação a objetos em JavaScript. É apenas uma forma mais simples e clara de criar objetos e lidar com herança.

Vantagens

  • Sintaxe simples e convencional.
  • Mais familiar para as pessoas com base em linguagem baseada em classe.
  • Antes do ES6, haviam várias implementações. Agora, apenas uma.

Desvantagens

  • Não é possível instanciar uma classe sem o new.
  • Os detalhes na instanciação ficam expostos para a API de chamada.
  • Quebram o princípio aberto / fechado. Ou seja, uma API deve estar aberta para extensão, mas fechada para modificação.
  • Tentação para criar heranças com extends.
  • Prolema ao migrar para funções fábrica.

Função Construtora

Um construtor é basicamente uma função. Ela pode ser executada como uma função ou pode ser utilizada para instanciar um objeto utilizando a palavra reservada new.

E se eu não usar o new?

Além do erro undefined, ela não utiliza o prototype e executa como uma função qualquer. E o this é referenciado no escopo global -window. Isso é claro, imaginando que a função construtora não possua uma validação para checar isso.

this faz referencia ao objeto criado pelo new.

Ao executar a função Cachorro com new, estamos fazendo quatro coisas:

  1. criando um novo objeto ({}).
  2. definindo o construtor do objeto cachorro como Cachorro.
  3. definindo o protótipo do objeto cachorro como Cachorro.prototype.
  4. executando a função Cachorro dentro do escopo do novo objeto, criando assim, uma nova instância.

Utilizando a cadeia de protótipos, podemos atualizar propriedades ou inserir novos métodos em objetos criados a partir de funções construtoras. E considerando que a cada nova instância as funções seriam criadas novamente, é uma boa prática criar as funções fora do construtor.

É uma boa prática usar a primeira letra maiúscula nos nomes de funções construtoras.

Vantagens

  • Menos verbosa.
  • Possibilidade de criar métodos e propriedades privadas.
  • Reusabilidade
  • Ideais para objetos que podem existir como múltiplas instâncias no mesmo contexto.
  • prototype é mais eficiente tanto em uso de memória quanto de CPU.
  • Instanciar um objeto sem se preocupar com efeitos colaterais.
  • Ajuda a ter um código padronizado, flexível e seguro.

Desvantagens

  • Sempre que instanciarmos um novo objeto, será criado um espaço na memória.
  • Utiliza o operador new que pode ser incompreendido por muitos.
  • Uso do this.

Função Fábrica

Podemos resumir uma função fábrica como um gerador de objetos.

Em JavaScript, qualquer função pode retornar um objeto. Mas, quando isso acontece sem o new, é uma função de fábrica. Ou seja, quando uma função não é uma classe ou um construtor, é uma função fábrica.

A partir do ES6, se você tiver variáveis ​​no escopo com o mesmo nome que o nome de propriedade pretendido, você pode omitir os dois pontos e o valor na criação do objeto literal.

Vantagens

  • Facilita a criação de novos objetos com o reuso.
  • Mais simples e clara que a construtora.
  • O possível uso de closures.
  • Restringe o uso do this.
  • Poderíamos criar uma função estática e privada para a classe. Visto que, qualquer função/objeto possui propriedades e métodos.

Desvantagens

  • Um pouco mais burocrática e verbosa em relação a construtora.
  • Um pouco menos performática em relação a construtora.

Conclusão, qual a melhor?

Pode se dizer que não existe uma resposta unânime entre os desenvolvedores. É uma questão de design e preferência. Até hoje muitos autores divergem opiniões sobre o assunto. Ou seja, utilize o bom senso.

Para mais detalhes eu recomendo o link abaixo: