Passei um bom tempo desenvolvendo widgets simples para projetos da seguinte maneira:
var project = project || {};
(function() {
project.elements = {
prop1: val1,
prop2: val2
}
project.method1 = function(val) {
// Do this
}
project.method2 = function(val) {
// Do that
}
project.init = function() {
project.method1(project.elements.prop1)
project.method2(project.elements.prop2)
}
})()
project.init();
Mas comecei a mudar meu formato para o seguinte:
function Project() {
this.elements = {
prop1: val1,
prop2: val2
}
this.method_one(this.elements.prop1);
this.method_two(this.elements.prop2);
}
Project.prototype.method_one = function (val) {
//
};
Project.prototype.method_two = function (val) {
//
};
new Project();
É verdade que estes são exemplos tolos, por isso não se enrole no eixo. Mas qual é a diferença funcional e quando devo escolher um ou outro?
design-patterns
javascript
prototyping
JDillon522
fonte
fonte
project
declaração dentro da função. Atualizada.Respostas:
A primeira diferença pode ser resumida como:
this
refere-se à Instância da classe.prototype
refere-se à definição .Digamos que temos a seguinte classe:
Então, aqui estamos nos anexando
this.number
a todas as instâncias da classe, e faz sentido, porque todasFlight
devem ter seu próprio número de voo.Por outro lado,
prototype
define uma única propriedade que pode ser acessada por todas as instâncias.Agora, se quisermos obter o número do voo, podemos simplesmente escrever o seguinte trecho e todas as nossas instâncias receberão uma referência a esse objeto recém-protegido.
A segunda diferença é sobre a maneira como o JavaScript procura uma propriedade de um objeto. Quando você está procurando
Object.whatever
, o JavaScript vai até o objeto Objeto principal (o objeto que todo o resto herdou) e, assim que encontrar uma correspondência, ele retornará ou o chamará.Mas isso só acontece para as propriedades prototipadas. Portanto, se você tiver algum lugar nas camadas mais altas
this.whatever
, o JavaScript não o considerará uma correspondência e continuará a pesquisa.Vamos ver como isso acontece na realidade.
Primeira nota que [quase] tudo são objetos em JavaScript. Tente o seguinte:
Agora vamos ver o que está dentro de um
Object
(observe MaiúsculasO
e.
no final). Nas Ferramentas do desenvolvedor do Google Chrome, quando você digita,.
você obterá uma lista de propriedades disponíveis dentro desse objeto específico.Agora faça o mesmo para
Function
:Você pode perceber o
name
método. Vá em frente e vamos ver o que acontece:Agora vamos criar uma função:
E vamos ver se temos o
name
método aqui também:Você deve ter uma string vazia, mas tudo bem. Você não deve receber um erro ou exceção.
Agora, vamos adicionar algo a esse deus
Object
e ver se o encontramos em outros lugares também?E lá vai você:
Em todos os casos, você deve ver
"Okay!"
.Com relação aos prós e contras de cada método, você pode considerar a prototipagem como uma maneira "mais eficiente" de fazer as coisas, pois mantém uma referência em todas as instâncias, em vez de copiar toda a propriedade em cada objeto. Por outro lado, é um exemplo de acoplamento apertado, que é um grande não-não até que você possa realmente justificar o motivo.
this
é bem mais complicado, pois é relevante para o contexto. Você pode encontrar muitos bons recursos gratuitamente na internet.Dito isso, ambas as formas são apenas ferramentas de linguagem e realmente depende de você e do problema que você está tentando resolver para escolher o que melhor se encaixa.
Se você precisar ter uma propriedade relevante para todas as instâncias de uma classe, use
this
. Se você precisar ter uma propriedade para funcionar da mesma maneira em todas as instâncias, useprototype
.Atualizar
Em relação aos snippets de amostra, o primeiro é um exemplo de Singleton , portanto, faz sentido usar
this
no corpo do objeto. Você também pode melhorar seu exemplo, tornando-o modular assim (e nem sempre é necessário usá-lothis
).Seu segundo snippet não faz muito sentido, porque primeiro você está usando
this
e depois está tentando hackearprototype
, o que não funciona porquethis
tem prioridadeprototype
. Não sei ao certo quais eram suas expectativas com relação a esse pedaço de código e como ele estava funcionando, mas eu recomendo que você o refatorasse.Atualizar
Para elaborar a
this
precedênciaprototype
, posso mostrar um exemplo e explicar como ele pode ser explicado, mas não tenho nenhum recurso externo para fazer backup.O exemplo é muito simples:
A explicação é, como sabemos,
this
é relevante para o contexto. Portanto, ele não existirá até que o contexto esteja pronto. Quando o contexto está pronto? Quando a nova instância está sendo criada! Você deve adivinhar o resto agora! Isso significa que, embora exista umaprototype
definição, masthis
faz mais sentido ter precedência, porque é tudo sobre a nova instância sendo criada naquele momento.fonte
this
no exemplo de protótipo bobo porquethis
se refere a suas próprias propriedades, incluindo seus métodos. Eu não aprendo o melhor lendo sobre código, mas mais olhando para código. ( Parte da MDN , Object Playground (incrível) e algumas outras). Você pode apontar para algo que explica o que você quer dizer com "this
tem prioridade sobreprototype
"? Eu gostaria de investigar mais.