As funções construtoras em JavaScript são como as classes do Java, diferenciando apenas pela sintaxe. Em questão de funcionamento, tanto funções contrutoras no JavaScript quanto Classes no Java têm a mesma utilidade: servir de molde para a criação de objetos.
Para construir objetos, funções construtoras precisam ser instanciadas pelo operador new. O this dentro delas se referencia ao objeto criado a partir delas.
No exemplo abaixo, a função Carro é uma função construtora, e carro1 é um objeto criado a partir do “molde” dessa classe, usando o operador new:
function Carro(marca, modelo, ano){
this.marca = marca
this.modelo = modelo
this.ano = ano
}
const carro1 = new Carro('Charger', 'RT', 1970)
console.log(carro1)
O JavaScript tem uma palavra reservada para classes?
Sim, existe um termo reservado para designar classes. No entanto, sua finalidade é ajudar a quem já sabe Java, para que fique mais familiarizado. Em se tratando de diferenças por herança, as classes no JavaScript não modificam em nada, e no fim elas se traduzem para funções.
Mas o que isso quer dizer? Isso significa que as classes no JavaScript são um tipo de função. Podemos constatar isso quando criamos uma classe ou uma função, e no final imprimir o Object.getPrototypeOf de cada uma delas.
Para classe, temos:
const classe = class{}
console.log(Object.getPrototypeOf(classe))
O retorno do console.log é [Function (anonymous)].
Para função, temos:
const funcao = function(){}
console.log(Object.getPrototypeOf(funcao))
E o console.log também imprime [Function (anonymous)].
Por isso é comum dizer que tudo em JavaScript é função! Por causa desses protótipos, qualquer função pode virar uma instância de construtor quando usado o operador new.
É preciso um return para ser considerado uma função construtora?
Normalmente, os construtores não têm um return. Isso acontece porque tudo o que lhes é informado é simplesmente passado ao this.
Por outro lado, havendo um return os comportamentos esperados são dois:
- Se o return for chamado com um objeto, ele irá retornar no lugar do this.
- Se o return for vazio ou seguido de um valor primitivo, ele será ignorado.
Nesse exmplo, o return está sendo utilizado dentro de um construtor seguido de um objeto:
function Aluno() {
this.nome = "Miguel"
return { nome: "Alexa" } // esse será o objeto retornado!
}
console.log(new Aluno().nome) // de fato, retornou "Alexa"
Já nesse caso, o return é vazio:
function Aluno() {
this.nome = "Miguel"
return // return vazio!
}
console.log(new Aluno().nome )// Acessa o this do construtor, que é Miguel
Qual a diferença entre retornar um objeto literal e um criado por função construtora?
Ao se criar objetos usando funções construtoras em JavaScript, estes seguirão o molde definido pela função, recebendo seus atributos e métodos.
Para criar objetos literais, é necessário um controle para garantir que os objetos tenham as mesmas propriedades. Uma solução é criá-los com uma função factory (“fábrica”), que garante o retorno de objetos literais com características explícitas. As funções factory são semelhantes às construtoras, mas sem o uso do new.