W3docs

Operador new em JavaScript

Aprenda como funções construtoras e o operador new criam objects em JavaScript: o que o new faz passo a passo, regra de retorno, new.target e convenções de nomes.

Introdução a Construtores e ao Operador new

Em JavaScript, construtores são funções projetadas para inicializar objects recém-criados. Eles desempenham um papel fundamental na programação orientada a objetos, permitindo que desenvolvedores definam propriedades e comportamentos que objects de uma determinada classe devem ter. O operador new é utilizado para criar uma instância de um object com base em uma função construtora, configurando um novo ambiente de object a partir do protótipo especificado e executando o construtor para inicializar o novo object.

Como os Construtores Funcionam

Uma função construtora em JavaScript se parece com qualquer outra função, mas é convencionalmente nomeada com uma letra maiúscula para diferenciá-la de funções comuns. Quando o operador new invoca uma função construtora, quatro coisas acontecem nos bastidores, equivalentes aproximadamente a este pseudocódigo:

function User(name) {
  // this = {};  (1) an empty object is created and assigned to this
  // this.__proto__ = User.prototype;  (2) prototype is linked

  this.name = name;  // (3) the constructor body runs, adding properties to this

  // return this;  (4) this is returned automatically
}
  1. Um novo object vazio é criado e atribuído a this.
  2. O protótipo é vinculado: o [[Prototype]] interno do novo object é definido como a propriedade prototype do construtor, de modo que ele herda propriedades e métodos definidos ali.
  3. O corpo do construtor é executado: a função é executada com os argumentos passados, e this refere-se ao object recém-criado, de modo que atribuições como this.name = name anexam propriedades a ele.
  4. O object é retornado: this é retornado automaticamente, a menos que o construtor retorne explicitamente um object diferente (veja A regra do valor de retorno abaixo).
Informação

O JavaScript moderno usa a sintaxe de class para definir construtores e métodos de forma mais intuitiva. Isso oferece uma abordagem mais direta e baseada em classes, semelhante a outras linguagens de programação.

Exemplo: Função Construtora Básica

javascript— editable

Explicação: Neste exemplo, User é uma função construtora que inicializa name, age e um método greet nos objects recém-criados. A instrução new User('John', 30) cria uma nova instância de User com o nome "John" e idade 30. Dentro de greet, this refere-se ao object no qual o método foi chamado.

A regra do valor de retorno

Construtores normalmente não usam return — o novo object (this) é retornado automaticamente. Mas return tem um comportamento especial e fácil de não perceber dentro de um construtor:

  • Se return for seguido de um object, esse object é retornado no lugar de this.
  • Se return for seguido de um primitivo (string, number, boolean, undefined, etc.), ele é ignorado e this é retornado normalmente.
javascript— editable

Explicação: WithObject retorna um object simples, de modo que esse object substitui completamente a instância. WithPrimitive retorna uma string, que é ignorada, portanto o this original (com name: 'Alice') é retornado. Raramente você vai depender disso, mas isso explica resultados surpreendentes quando um construtor retorna acidentalmente um valor.

Detectando new com new.target

Dentro de qualquer função, new.target é undefined quando a função é chamada normalmente e igual à própria função quando chamada com new. Isso permite que um construtor detecte como foi invocado — útil para impor (ou silenciosamente permitir) o uso da palavra-chave new.

javascript— editable

Explicação: Como Modal verifica new.target, chamar Modal('Without new') sem new é redirecionado de forma transparente para new Modal(...), de modo que b ainda é uma instância real de Modal. (Observação: muitas equipes preferem não fazer isso e deixar que a ausência de new gere um erro explícito.)

Quando devo usar um construtor?

Use uma função construtora (ou uma class) quando precisar criar muitos objects com a mesma estrutura — vários usuários, carros, widgets do DOM, etc. O construtor centraliza a lógica de configuração para que cada instância seja criada da mesma forma e compartilhe métodos por meio do protótipo.

Se você precisar de apenas um único object, um object literal simples { ... } é mais simples. Para um object único que ainda se beneficia de um corpo de construtor, você pode até usar um construtor anônimo:

javascript— editable

Explicação: A function anônima é executada uma única vez como construtora e não é salva em lugar nenhum, portanto não pode ser reutilizada — é apenas uma forma de encapsular uma configuração complexa de uso único.

Funções construtoras vs. classes

O código moderno geralmente prefere a sintaxe class, que é essencialmente açúcar sintático sobre funções construtoras e protótipos. Os dois trechos abaixo são equivalentes:

javascript— editable

As classes trazem benefícios reais em relação às funções construtoras: os métodos não são enumeráveis por padrão, o corpo é executado em modo estrito, chamar uma class sem new lança um erro, e extends/super tornam a herança muito mais limpa. As funções construtoras continuam sendo importantes de entender porque as classes são construídas sobre o mesmo mecanismo de protótipo, e você ainda as encontrará em código mais antigo.

Usando Construtores para Objects Complexos

Os construtores podem ser usados para estabelecer relações mais complexas entre objects, incluindo métodos que interagem com outras propriedades dos objects.

Exemplo: Construtor com Métodos

javascript— editable

Explicação: O construtor Car configura cada object carro com propriedades específicas e um método que exibe informações sobre o carro.

Exemplo: Métodos no Protótipo

javascript— editable

Explicação: Ao adicionar introduce ao protótipo de Employee, todas as instâncias compartilham o mesmo método, o que é mais eficiente em termos de memória do que defini-lo diretamente no construtor.

Aviso

Recomenda-se usar classes ES6 para definir objects e construtores para obter um código mais limpo e legível.

Boas Práticas com Construtores

Ao trabalhar com construtores em JavaScript, seguir certas boas práticas pode melhorar significativamente a legibilidade, eficiência e escalabilidade do seu código. A seguir, as práticas são detalhadas com exemplos e explicações:

1. Convenção de Nomenclatura

Boa Prática: Sempre inicie os nomes de construtores com letra maiúscula para diferenciá-los de funções comuns. Esta é uma convenção amplamente adotada em JavaScript e em muitas outras linguagens de programação que ajuda os desenvolvedores a identificar rapidamente funções construtoras.

Exemplo:

javascript— editable

Explicação: A função construtora Laptop começa com letra maiúscula, indicando que deve ser usada com o operador new para criar novos objects.

2. Separar a Lógica

Boa Prática: Para métodos que não precisam acessar dados individuais da instância, defina-os no protótipo do construtor em vez de dentro do próprio construtor. Essa abordagem economiza memória porque todas as instâncias compartilham o mesmo método, em vez de cada instância criar uma nova função na memória.

Exemplo:

javascript— editable

Explicação: O método describe é adicionado ao protótipo de Book, o que significa que todas as instâncias de Book compartilham o mesmo método describe. Isso é mais eficiente do que definir describe dentro do construtor, o que criaria uma nova função para cada instância do livro.

3. Valores de Retorno

Boa Prática: Evite retornar valores de construtores. Os construtores JavaScript retornam automaticamente a nova instância do object, a menos que um object diferente seja explicitamente retornado. Retornar valores não-object (como uma string ou um número) não terá efeito, e a nova instância ainda será retornada.

Exemplo:

javascript— editable

Explicação: Apesar de tentar retornar uma string do construtor Player, o JavaScript ignora esse valor de retorno porque não é um object. A nova instância de Player é retornada normalmente.

Conclusão

Compreender e utilizar construtores e o operador new em JavaScript é essencial para uma programação orientada a objetos eficaz. Seguindo as convenções e boas práticas descritas aqui, os desenvolvedores podem criar código organizado, eficiente e escalável. Os construtores fornecem um mecanismo poderoso para inicializar novos objects e definir seu comportamento de forma estruturada e intuitiva.

Para se aprofundar, explore como os construtores compartilham comportamento por meio da herança prototípica, como a sintaxe class se baseia nessas ideias, e como uma função também é um object com propriedades próprias.

Prática

Prática
O que acontece quando uma função é executada com 'new' em JavaScript?
O que acontece quando uma função é executada com 'new' em JavaScript?
Was this page helpful?