Em muitos casos que postei aqui e também em situações profissionais usei o Delegate (post anterior) e simplesmente ele resolveu vários problenas quando estava trabalhando com classes e perdia o escopo do objeto em alguns métodos.
A pouco, desenvolvendo uma nova classe, me deparei com um problema chato.
Seguem as Situações:
Tinha numa classe, no método [this.iniciar] um código que seria executado quando um evento ocorresse, mas ao passar o método para o evento, das duas uma: Ou Conseguia pegar o evento e o escopo era perdido (situação 1) ou tinha o escopo (usando o Delegate) porém não tinha o evento :( (situação 2). Segue abaixo os exemplos:
Situação 1:
...
this.iniciar = function() {
document.onmousemove = this.verifica;
}
this.verifica = function(e) {
// Tenho o evento mas não tenho o escopo
}
...
Situação 2:
...
this.iniciar = function() {
document.onmousemove = Delegate.create(this, this.verifica, Array(''));
}
this.verifica = function(e) {
// Tenho o escopo mas não tenho o evento
}
...
Consegui resolver o problema da seguinte maneira:
NomeDaClasse = function() {
with(this) {
...
this.iniciar = function() {
document.onmousemove = this.verifica;
}
this.verifica = function(e) {
// Tenho o evento
// Tenho o escopo
teste(); // Não use o this.teste();
}
this.teste = function() {
alert('Estou no escopo');
}
...
}
};
Imaginei que usando o with poderia ser uma luz e não acreditei que isso funcionaria até testar!!!
Obs.:
- No exemplo acima, se você usar o [this] dentro do evento, ou seja, dentro do método [this.verifica] você estará no escopo do objeto [document].
- Se você tiver uma função fora da classe com o nome idêntico de algum método da classe não vai dar conflito, porém você não vai acessar a função externa também!
Quando você está programando em Javascript Orientado a Objetos, você pode se deparar com diversos problemas e um deles é a perda de escopo do objeto (this). Uma solução simples é usar a classe Delegate, em poucas palavras ela executa uma função/método no contexto do objeto original.
Delegate = {
create: function (obj, func, params) {
var f = function() { return func.apply(obj, params); };
return f;
}
}
Exemplo da implementação:
...
this.a = function() {
// Não chame a função this.b() desta forma,
// pois ela executará antes do tempo correto
setTimeout(Delegate.create(this, this.b, Array('')), 1000);
}
this.b = function() {
alert(this.c());
}
this.c = function() {
return 'Olá';
}
...
Os métodos ‘definirClasses‘ e ‘definirBotaoFechar‘ não são obrigatórios, se não forem invocados executarão suas situações padrões.
O que cada um faz…
definirClasses = Define uma classe CSS para os elementos onde pode-se, via CSS ajustar cores, bg’s e etc. definirBotaoFechar = Define a imagem do ‘close’ da foto, se não for invocado o evento ‘close’ acontecerá quando a foto for clicada.