Javascript: Closure

Em um determinado ponto do projeto no qual trabalho havia a necessidade de que a mesma função que fazia a chamada Ajax, fosse também a função de callback. Isto é fácil, eu sei. Mas havia mais um problema: essa função na verdade era um método de uma classe, e eu precisava obter os dados de todo o objeto para trabalhar no callback.

Como assim? Vou apresentar um exemplo, entretanto, está totalmente direcionado ao DWR, um framework Java para trabalhar com Ajax. Em DWR você tem uma “classe” Javascript que reflete exatamente os métodos de uma classe Java. Portanto, em Javascript você poderia fazer algo do tipo:

MinhaClasse.meuMetodo("dadosParaEnviar", funcaoCallback);

No meu caso, o parâmetro funcaoCallback era um método de uma classe. Veja este trecho de código:

// Classe criada com Prototype.var m = Class.create();
m.prototype = {   // Construtor.
   initialize: function(){
      this.atributoQualquer = 10;
   },// Método Callback.

   callback: function(data) {
      alert(this.atributoQualquer);
   },

// Chamada Ajax.
   chamarAjax: function() {
      MinhaClasse.meuMetodo("dadosParaEnviar", this.callback);
   }
}

O que será impresso no alert quando houver o retorno da chamada Ajax? O número 10? Errado, pois seu método agora está fora do contexto do seu objeto. Vai ser impresso NULL ou UNDEFINED ou nada mesmo.

Como resolver? Eu usei closures em Javascript. Este mesmo código ficaria desta forma:

// Criar uma variável $this com referência ao próprio objeto.var
$this = this ;// Criar a closure.

// Está será a função a ser chamada no callback.
var callbackProxy = function(dataFromServer) {

// Quando ocorrer o retorno do Ajax no servidor,
// então chama o método preencherCombo.
$this.preencherCombo(dataFromServer);
} ;

// Metadados.
var callMetaData = { callback: callbackProxy } ;

MinhaClasse.meuMetodo("dadosParaEnviar", callMetaData);

Bom, é isso. Ficou confuso? Sugiro uma leitura deste texto.

×