W3docs

Protótipos Nativos do JavaScript

Aprenda como os protótipos nativos do JavaScript funcionam: Object.prototype na raiz da cadeia, protótipos de Array, Function e Number, empréstimo de métodos com call e apply, e por que estender protótipos nativos é desencorajado.

Explorando Protótipos Nativos

Os protótipos nativos em JavaScript são os objetos que construtores embutidos como Array, Object, String, Number e Function utilizam para compartilhar métodos e propriedades com cada valor que criam. Quando você chama [1, 2, 3].map(...) ou "hi".toUpperCase(), o método que você está chamando não existe no próprio array ou string — ele está em Array.prototype ou String.prototype e é encontrado ao percorrer a cadeia de protótipos.

Esta página explica onde esses protótipos se situam na cadeia, como inspecioná-los, como emprestar seus métodos para objetos que não são arrays reais, e por que estendê-los permanentemente é desencorajado. Se você é novo ao funcionamento da própria cadeia, leia herança prototípica primeiro.

O Papel dos Protótipos Nativos

Os protótipos nativos são fundamentais para o JavaScript: eles são a razão pela qual cada valor literal vem pré-carregado com métodos úteis sem que você precise definir nada. Aprender como eles se encaixam na cadeia de protótipos permite entender mensagens de erro, reutilizar métodos embutidos em contextos inesperados e evitar bugs sutis.

Object.prototype: a Raiz da Cadeia

Quase todo objeto que você cria herda eventualmente de Object.prototype, que está no topo da cadeia. É de lá que vêm métodos como toString, hasOwnProperty e valueOf. Quando uma busca falha em um objeto e em todos os protótipos intermediários, a cadeia termina em Object.prototype, e o próximo elo é null.

javascript— editable

Protótipos de Array, Function e Number

Os tipos embutidos adicionam seu próprio protótipo sobre Object.prototype. Um array, por exemplo, herda de Array.prototype (que fornece map, filter, push, …), e Array.prototype por sua vez herda de Object.prototype. O mesmo padrão se aplica a funções e números.

javascript— editable

Emprestando Métodos com call e apply

Como os métodos nativos residem nos protótipos, você pode emprestá-los e executá-los sobre qualquer valor compatível usando call ou apply. O exemplo clássico é usar métodos de Array.prototype em objetos semelhantes a arrays (como arguments ou uma string) que não possuem esses métodos por conta própria.

javascript— editable

Estendendo Protótipos Nativos

Embora o JavaScript permita estender protótipos nativos, essa prática é geralmente desencorajada no escopo global devido a possíveis conflitos em bases de código maiores ou em scripts de terceiros. Há vários motivos concretos para evitá-la:

  • Colisões de nomes. Se dois scripts adicionam um método com o mesmo nome (ou uma versão futura do ECMAScript padroniza esse nome com comportamento diferente), um sobrescreve silenciosamente o outro.
  • Enumerabilidade. Um método adicionado com atribuição simples é enumerável, portanto aparece em loops for...in sobre cada objeto desse tipo, a menos que seja protegido com hasOwnProperty — uma fonte comum de bugs.
  • Efeitos colaterais globais. A alteração afeta todos os valores desse tipo em todo o programa, incluindo código que você não escreveu.

O trecho abaixo mostra a armadilha do for...in. Uma atribuição normal vaza para o loop; usar Object.defineProperty para tornar o método não-enumerável não ocorre o mesmo.

javascript— editable

Compreender essa capacidade ainda vale a pena para reconhecer possíveis problemas, ler polyfills e explorar padrões avançados em ambientes controlados.

Exemplos Práticos de Trabalho com Protótipos Nativos

Manipulando Arrays com Array.prototype

Considere o poder de Array.prototype, que oferece métodos como map, filter e reduce. Esses métodos fornecem soluções elegantes para transformar e manipular dados armazenados em arrays. Podemos adicionar novos métodos manipulando o Array.prototype


javascript— editable

Neste exemplo, definimos um novo método mapToSquare no protótipo, que usa o método embutido map para retornar o quadrado de cada número.

Aprimorando Strings com String.prototype

String.prototype é outro rico repositório de métodos, como toLowerCase, toUpperCase e includes, que facilitam operações de manipulação e consulta de strings.


javascript— editable

Neste exemplo, definimos removeSpace no protótipo, usando split, filter e join para remover espaços.

Aprimoramentos Personalizados em Protótipos Nativos

Embora seja recomendável ter cautela, adicionar métodos personalizados a protótipos nativos pode demonstrar a flexibilidade do JavaScript. Veja como você poderia estender Array.prototype para incluir um método que calcula a soma dos elementos de um array:


javascript— editable

Este método personalizado, sum, adiciona uma nova dimensão ao protótipo de Array, ilustrando tanto o potencial quanto os riscos de estender protótipos nativos.

Boas Práticas para Usar Protótipos Nativos

Embora o poder dos protótipos nativos seja inegável, aqui estão algumas boas práticas para garantir que seu código permaneça robusto e livre de conflitos:

  • Evite Estender Protótipos Nativos: A menos que seja absolutamente necessário, evite modificar protótipos embutidos para prevenir comportamentos inesperados no seu código ou em bibliotecas de terceiros.
  • Use Object.defineProperty para Extensões Mais Seguras: Quando precisar adicionar métodos, use Object.defineProperty para torná-los não-enumeráveis. Isso evita que loops for...in capturem suas propriedades personalizadas e reduz conflitos de nomenclatura.
  • Use Polyfills com Sabedoria: Ao usar polyfills para adicionar funcionalidades ausentes em navegadores mais antigos, certifique-se de que eles verificam a existência do método antes de adicioná-lo ao protótipo.
  • Aproveite os Recursos Modernos do JavaScript: Com a evolução do JavaScript, muitas tarefas que antes exigiam estender protótipos nativos agora podem ser realizadas com novas construções da linguagem, como classes e módulos.

Conclusão

Os protótipos nativos são o mecanismo por trás de cada método embutido que você usa diariamente: eles estão na cadeia de protótipos, com Object.prototype na raiz, e permitem que valores como arrays, funções e números compartilhem comportamento. Saber como inspecioná-los com Object.getPrototypeOf, emprestar seus métodos com call e apply, e resistir ao impulso de estendê-los globalmente tornará seu código mais capaz e mais previsível.

Para se aprofundar, consulte herança prototípica para entender como a cadeia é construída, e métodos de protótipo e objetos sem __proto__ para a API moderna Object.create / Object.getPrototypeOf.

Prática

Prática
O que é verdade sobre estender protótipos nativos em JavaScript?
O que é verdade sobre estender protótipos nativos em JavaScript?
Was this page helpful?