O que significa que o Javascript é uma linguagem baseada em protótipo?

255

Diz-se que uma das principais vantagens do Javascript é que é uma linguagem baseada em protótipo.

Mas o que significa que o Javascript é baseado em protótipo e por que isso é uma vantagem?

Jonas Pegerfalk
fonte
3
Esta resposta explica tudo o que você precisa saber sobre a herança prototípica: stackoverflow.com/a/16872315/783743
Aadit M Shah

Respostas:

291

A herança prototípica é uma forma de reutilização de código orientada a objetos . Javascript é uma das únicas linguagens orientadas a objetos [mainstream] a usar herança prototípica. Quase todas as outras linguagens orientadas a objetos são clássicas.

Na herança clássica , o programador escreve uma classe, que define um objeto. Vários objetos podem ser instanciados da mesma classe, para que você tenha um código em um local que descreva vários objetos em seu programa. As classes podem ser organizadas em uma hierarquia, promovendo a reutilização de código. Um código mais geral é armazenado em uma classe de nível superior, da qual as classes de nível inferior herdam. Isso significa que um objeto está compartilhando código com outros objetos da mesma classe, bem como com suas classes pai.

Na forma de herança prototípica , os objetos são herdados diretamente de outros objetos. Todos os negócios sobre aulas desaparecem. Se você quer um objeto, basta escrever um objeto. Mas a reutilização de código ainda é uma coisa valiosa; portanto, os objetos podem ser vinculados em uma hierarquia. Em javascript, todo objeto possui um link secreto para o objeto que o criou, formando uma cadeia. Quando um objeto solicita uma propriedade que não possui, seu objeto pai será solicitado ... continuamente na cadeia até que a propriedade seja encontrada ou até que o objeto raiz seja atingido.

Cada função no JavaScript (que são objetos em si), na verdade, possui um membro chamado "prototype", responsável por fornecer valores quando um objeto é solicitado. Ter esse membro permite que o mecanismo construtor (pelo qual objetos são construídos a partir de funções) funcione. A adição de uma propriedade ao protótipo de um objeto de função tornará disponível para o objeto construído, bem como para todos os objetos que herdam dele.

Vantagens

Pode não haver uma regra rígida e rápida sobre por que a herança prototípica é uma forma vantajosa de reutilização de código. A reutilização de código em si é vantajosa e a herança prototípica é uma maneira sensata de fazer isso. Você pode argumentar que a herança prototípica é um modelo bastante simples de reutilização de código e que o código pode ser fortemente reutilizado de maneira direta . Mas as línguas clássicas certamente são capazes de fazer isso também.

Sidenote: @Andrew Hedges argumenta, que na verdade existem muitas linguagens prototípicas. Vale a pena notar que esses outros existem, mas também vale a pena notar que nenhum deles é próximo do convencional. O NewtonScript parecia ter alguma tração por um tempo, mas morreu com sua plataforma. Também é possível estender algumas linguagens modernas de maneira a adicionar recursos prototípicos.

keparo
fonte
9
Hey Kelly. Enquanto JavaScript é , de longe, a língua prototypal mais popular, existem muitas outras: en.wikipedia.org/wiki/Prototype-based_programming#Languages
Andrew Hedges
2
Olá, Andrew. Bom ponto. Eu deveria ter sido mais claro. Eu vou tomar nota disso.
9338 keparo
3
Por favor, leia isto também developer.mozilla.org/en/JavaScript/Guide/…
pramodc84
1
+1 para uma ótima resposta. Um pequeno comentário: para mim, a herança clássica parece mais "direta" do que prototípica. De fato, eu realmente vejo o objeto protótipo como mera ligação (a outros objetos), enquanto que em um OOP compilado considero a classe base como "herdada diretamente". Como tal, os objetos prototípicos são encadeados em vez de herdados (a herança é um tanto falsa). Alguma ideia?
Prisioneiro ZERO
3
@PrisonerZERO: Eu diria que a herança prototípica é mais direta que a clássica. Em vez de o objeto B apontar para uma classe que herda da classe para a qual o objeto A aponta, ele aponta diretamente para o objeto A e diz "sou exatamente como esse objeto, exceto ...". A grande coisa sobre herança prototípica, e a coisa que parece mais difícil para a maioria das pessoas internalizar, é que ela não distingue instâncias de tipos. Cada objeto é tanto um tipo e uma instância. As distinções entre os dois são artificiais e deliberadas, e geralmente são um sintoma de estar preso a uma mentalidade orientada para a classe.
cHao 17/02
54

Uma linguagem baseada em protótipo, não faz a distinção entre classes e objetos: simplesmente possui objetos. Uma linguagem baseada em protótipo tem a noção de um objeto prototípico, um objeto usado como modelo para obter as propriedades iniciais de um novo objeto. Qualquer objeto pode especificar suas próprias propriedades, quando você o cria ou no tempo de execução. Além disso, qualquer objeto pode ser associado como protótipo para outro objeto , permitindo que o segundo objeto compartilhe as propriedades do primeiro objeto.

Guido
fonte
6
Uma explicação muito boa, mas um pouco enganosa com o comentário sobre o "modelo para propriedades iniciais". Se você alterar o protótipo APÓS instanciar um objeto, esse objeto ainda receberá essas funções.
nickf
32

A programação baseada em protótipo é um estilo de programação orientada a objetos em que as classes não estão presentes e a reutilização do comportamento (ou herança em linguagens baseadas em classes) é realizada pela clonagem de objetos existentes que servem como protótipos.

CMS
fonte
Você ainda se sente assim? Porque se assim for, então esta é a primeira explicação para realmente apenas "clicar" solidamente comigo.
Chazt3n 18/05/19
11

A vantagem / desvantagem é que podemos criar novos tipos de objetos em tempo de execução sem precisar definir classes (código estático). Como a maioria dos recursos, cabe ao desenvolvedor transformá-lo em uma vantagem / desvantagem.

Acima é possível porque os objetos são essencialmente funções no script java (fechamentos também).

questzen
fonte
Objetos dinâmicos são um benefício do javascript, mas não estão realmente relacionados ao javascript ser uma linguagem prototípica ou funcional. Em muitas linguagens clássicas, você pode criar objetos dinâmicos em tempo de execução. Os fechamentos também não são relacionados.
3112 keparo
2
As classes não são necessariamente um código estático - dê uma olhada no Python, em que as classes são objetos em si e são construídas a partir de metaclasses que também são objetos.
Tomasz Zieliński
6

Em vez de declarar uma estrutura de classe, você pode criar objetos do mesmo tipo e adicionar à definição deles sempre que desejar, usando o protótipo do objeto. É mais flexível do que a maneira normal de fazer as coisas.

Greg
fonte
6

Se você apenas usar objetos em tempo de execução em vez de uma classe em compilação para criar novos objetos, isso abrirá a possibilidade de estender um objeto sem conhecer detalhes sobre ele. Obviamente, isso pode se tornar uma desvantagem rapidamente, dependendo do uso. Não faço suposições sobre o idioma aqui, por isso é aplicável a outros idiomas além do javascript que não são tão dinâmicos.

myobject.prototype=unkownobject;
myobject.newproperty=1;

Você pode obter o objeto de qualquer lugar; seu próprio código, da rede, do banco de dados, da ligação externa e assim por diante.

Observe que uma linguagem não precisa implementar a herança de protótipo como javascript. Em javascript, um objeto protótipo é meramente compartilhado, assim como suas propriedades, entre os herdeiros. A alternativa é copiar todas as propriedades do protótipo para o novo objeto. Cada abordagem tem seus pontos fortes em diferentes situações. Eu gosto mais do segundo, mas não é o que o javascript faz.

artificialidiot
fonte
6

Depois de ler todas as respostas, esta é a conclusão

1) Herança na qual objetos são herdados diretamente de outros objetos

2) Isso não usa classes

3) Também chamada de programação baseada em instância ou programação orientada a protótipo sem classe

4) A reutilização do comportamento é realizada pela clonagem de objetos existentes que servem como protótipos

5) O objeto usado como modelo no novo objeto obtém propriedades iniciais

Sunil Garg
fonte