No JavaScript, todo objeto é ao mesmo tempo uma instância e uma classe. Para fazer herança, você pode usar qualquer instância de objeto como um protótipo.
Em Python, C ++, etc. existem classes e instâncias como conceitos separados. Para fazer herança, você precisa usar a classe base para criar uma nova classe, que pode ser usada para produzir instâncias derivadas.
Por que o JavaScript foi nessa direção (orientação a objeto baseada em protótipo)? Quais são as vantagens (e desvantagens) do OO baseado em protótipo em relação ao OO tradicional baseado em classe?
javascript
oop
inheritance
prototype-programming
Stefano Borini
fonte
fonte
GEB
?Respostas:
Existem cerca de cem problemas de terminologia aqui, a maioria criada em torno de alguém (não você) tentando fazer com que a ideia deles pareça o melhor.
Todas as linguagens orientadas a objetos precisam ser capazes de lidar com vários conceitos:
Agora, na comparação:
A primeira coisa é toda a pergunta "classe" vs "protótipo". A idéia começou originalmente em Simula, onde, com um método baseado em classe, cada classe representava um conjunto de objetos que compartilhavam o mesmo espaço de estado (leia "valores possíveis") e as mesmas operações, formando assim uma classe de equivalência. Se você olhar para Smalltalk, como é possível abrir uma classe e adicionar métodos, é efetivamente o mesmo que você pode fazer em Javascript.
As linguagens OO posteriores queriam poder usar a verificação de tipo estático, então obtivemos a noção de uma classe fixa definida em tempo de compilação. Na versão de classe aberta, você tinha mais flexibilidade; na versão mais recente, você tinha a capacidade de verificar alguns tipos de correção no compilador que, de outra forma, exigiriam testes.
Em uma linguagem "baseada em classe", essa cópia ocorre no momento da compilação. Em uma linguagem de protótipo, as operações são armazenadas na estrutura de dados do protótipo, que é copiada e modificada no tempo de execução. Abstratamente, porém, uma classe ainda é a classe de equivalência de todos os objetos que compartilham o mesmo espaço de estado e métodos. Ao adicionar um método ao protótipo, você efetivamente cria um elemento de uma nova classe de equivalência.
Agora, por que isso? principalmente porque cria um mecanismo simples, lógico e elegante em tempo de execução. agora, para criar um novo objeto ou para criar uma nova classe, basta executar uma cópia profunda, copiando todos os dados e a estrutura de dados do protótipo. Você obtém herança e polimorfismo mais ou menos de graça, então: a pesquisa de método sempre consiste em solicitar a um dicionário uma implementação de método por nome.
O motivo que acabou no script Javascript / ECMA é basicamente que, quando começamos com isso há 10 anos, estávamos lidando com computadores muito menos potentes e navegadores muito menos sofisticados. Escolher o método baseado em protótipo significava que o intérprete poderia ser muito simples, preservando as propriedades desejáveis da orientação a objetos.
fonte
Uma comparação, que é levemente tendenciosa em relação à abordagem baseada em protótipos, pode ser encontrada no artigo Self: The Power of Simplicity . O artigo apresenta os seguintes argumentos a favor dos protótipos:
O Self é provavelmente a primeira linguagem a implementar protótipos (também foi pioneira em outras tecnologias interessantes, como o JIT, que mais tarde entrou na JVM), portanto, a leitura dos outros papéis do Self também deve ser instrutiva.
fonte
point
é uma instância da classePoint
, que é uma instância da metaclassestandard-class
, que é uma instância de si mesma, ad finitum.Você deve conferir um ótimo livro sobre JavaScript de Douglas Crockford . Ele fornece uma explicação muito boa de algumas das decisões de design tomadas pelos criadores de JavaScript.
Um dos aspectos importantes do design do JavaScript é o seu sistema de herança prototípica. Objetos são cidadãos de primeira classe em JavaScript, tanto que funções regulares também são implementadas como objetos (objeto 'Function' para ser mais preciso). Na minha opinião, quando foi originalmente projetado para ser executado dentro de um navegador, deveria ser usado para criar muitos objetos singleton. No DOM do navegador, você encontra essa janela, documento, etc. todos os objetos singleton. Além disso, o JavaScript é uma linguagem dinâmica de tipo fraco (ao contrário do Python, que é fortemente tipado, linguagem dinâmica); como resultado, um conceito de extensão de objeto foi implementado através do uso da propriedade 'prototype'.
Então, acho que existem alguns profissionais para o OO baseado em protótipo, conforme implementado em JavaScript:
Aqui estão alguns dos contras da OO prototípica:
fonte