Protótipos são uma otimização .
Um ótimo exemplo de como usá-los bem é a biblioteca jQuery. Cada vez que você obtém um objeto jQuery usando $('.someClass')
, esse objeto tem dezenas de "métodos". A biblioteca pode conseguir isso retornando um objeto:
return {
show: function() { ... },
hide: function() { ... },
css: function() { ... },
animate: function() { ... },
// etc...
};
Mas isso significaria que cada objeto jQuery na memória teria dezenas de slots nomeados contendo os mesmos métodos, continuamente.
Em vez disso, esses métodos são definidos em um protótipo e todos os objetos jQuery "herdam" esse protótipo para obter todos esses métodos com um custo de tempo de execução muito pequeno.
Uma parte vitalmente importante de como o jQuery acerta é que isso é escondido do programador. É tratado puramente como uma otimização, não como algo com que você precisa se preocupar ao usar a biblioteca.
O problema com o JavaScript é que as funções do construtor simples exigem que o chamador se lembre de prefixá-las com new
ou de outra forma normalmente não funcionam. Não há um bom motivo para isso. O jQuery acerta ao esconder esse absurdo atrás de uma função comum $
, então você não precisa se preocupar com a forma como os objetos são implementados.
Para que você possa criar convenientemente um objeto com um protótipo especificado, o ECMAScript 5 inclui uma função padrão Object.create
. Uma versão bastante simplificada ficaria assim:
Object.create = function(prototype) {
var Type = function () {};
Type.prototype = prototype;
return new Type();
};
Ele apenas cuida da dor de escrever uma função de construtor e, em seguida, chamá-la com new
.
Quando você evitaria protótipos?
Uma comparação útil é com linguagens OO populares, como Java e C #. Eles suportam dois tipos de herança:
- interface de herança, onde
implement
uma interface
tal forma que a classe fornece sua própria implementação exclusivo para cada membro da interface.
- implementação de herança, onde
extend
um class
que fornece implementações padrão de alguns métodos.
Em JavaScript, a herança prototípica é um tipo de herança de implementação . Portanto, nas situações em que (em C # ou Java) você teria derivado de uma classe base para obter o comportamento padrão, no qual você faria pequenas modificações por meio de substituições, em JavaScript, a herança prototípica faz sentido.
No entanto, se você estiver em uma situação em que usaria interfaces em C # ou Java, não precisará de nenhum recurso de linguagem específico em JavaScript. Não há necessidade de declarar explicitamente algo que representa a interface e não há necessidade de marcar objetos como "implementando" essa interface:
var duck = {
quack: function() { ... }
};
duck.quack(); // we're satisfied it's a duck!
Em outras palavras, se cada "tipo" de objeto tem suas próprias definições de "métodos", então não há valor em herdar de um protótipo. Depois disso, depende de quantas instâncias você aloca de cada tipo. Mas em muitos projetos modulares, existe apenas uma instância de um determinado tipo.
E, de fato, tem sido sugerido por muitas pessoas que a herança de implementação é má . Ou seja, se houver algumas operações comuns para um tipo, então talvez seja mais claro se elas não forem colocadas em uma classe base / super, mas apenas expostas como funções comuns em algum módulo, para o qual você passa o (s) objeto (s) você quer que eles operem.
quack
função estivesse em um protótipo, ao qual as muitas instâncias de pato estão vinculadas. 2. A sintaxe literal do objeto{ ... }
cria uma instância (não há necessidade de usarnew
com ela). 3. Chamar qualquer função JS faz com que pelo menos um objeto seja criado na memória - é chamado dearguments
objeto e armazena os argumentos passados na chamada: developer.mozilla.org/en/JavaScript/Reference/…Você deve usar protótipos se desejar declarar um método "não estático" do objeto.
fonte
this
exemplothis.getA = function(){alert("A")}
certo?Um motivo para usar o
prototype
objeto embutido é se você for duplicar um objeto várias vezes que compartilhará uma funcionalidade comum. Ao anexar métodos ao protótipo, você pode economizar na duplicação de métodos criados para cadanew
instância. Mas quando você anexa um método aoprototype
, todas as instâncias terão acesso a esses métodos.Digamos que você tenha uma
Car()
classe / objeto base .em seguida, você cria várias
Car()
instâncias.Agora, você sabe que cada carro precisará dirigir, ligar, etc. Em vez de anexar um método diretamente à
Car()
classe (que ocupa memória para cada instância criada), você pode anexar os métodos ao protótipo (criando apenas os métodos uma vez), dando acesso a esses métodos tanto para o novovolvo
quanto parasaab
.fonte
Car.prototype = { ... }
teria que vir antes de chamar um,new Car()
conforme ilustrado neste jsfiddle: jsfiddle.net/mxacA . Quanto ao seu argumento, esta seria a maneira correta de fazê-lo: jsfiddle.net/Embnp . O engraçado é que não me lembro de responder a esta pergunta =)Coloque funções em um objeto de protótipo quando for criar muitas cópias de um tipo específico de objeto e todos eles precisam compartilhar comportamentos comuns. Ao fazer isso, você economizará memória tendo apenas uma cópia de cada função, mas esse é apenas o benefício mais simples.
Alterar métodos em objetos de protótipo, ou adicionar métodos, muda instantaneamente a natureza de todas as instâncias do (s) tipo (s) correspondente (s).
Agora, exatamente por que você faria todas essas coisas é principalmente uma função do design de seu próprio aplicativo e dos tipos de coisas que você precisa fazer no código do lado do cliente. (Uma história totalmente diferente seria o código dentro de um servidor; muito mais fácil imaginar fazer código "OO" em grande escala lá.)
fonte
Se eu explicar em termos de classe, então Person é classe, walk () é o método Prototype. Portanto, walk () terá sua existência somente após você instanciar um novo objeto com this.
Portanto, se você deseja criar as cópias de um objeto como Pessoa, você pode criar muitos usuários, o Protótipo é uma boa solução, pois economiza memória compartilhando / herdando a mesma cópia de função para cada um dos objetos na memória.
Considerando que estática não é uma grande ajuda em tal cenário.
Então, com isso é mais como um método de instância. A abordagem do objeto é semelhante a métodos estáticos.
https://developer.mozilla.org/en/Introduction_to_Object-Oriented_JavaScript
fonte