Error de referencia al llamar a un método dentro de una función de escucha (Javascript)

function LolClass(){

    this.init = function(){             
        button_a.bind("tap", function(){                
            this.refreshFields(); // doesn't work 
            //refreshFields(); // doesn't work either
        });     
    }

    this.refreshFields = function(){
        alert("LOL");
    }

    this.dummy = function(){
        this.refreshFields(); // W O R K S!
    }
}

Cuando toco el button_a, aparece un error de referencia, ya que el método refreshFields no se "encuentra".

Error de referencia no capturado: refreshFields no está definido en file:///android_asset/www/src/pages/main.js:70

Pero si llamo a ese método en otros lugares que no sean ese oyente de toque, funciona.

Estoy totalmente seguro de que el this dentro de la función tap listener se hace referencia a button_a, el objetivo del evento.

Mi pregunta es: ¿Cuál es la mejor (oo) solución para eso?

preguntado el 12 de junio de 12 a las 18:06

Creo que el this se refiere a button_a, por lo que no está en el ámbito correcto. No estoy del todo seguro, pero es posible que deba pasar el objeto principal a la función para hacer referencia al interior. -

Qué es .bind()? ¿Es parte de alguna biblioteca? Si es así, ¿eso .bind() método aceptar un context ¿argumento? -

Tenga en cuenta que este patrón en javascript está en desuso. si olvidas el new operador, pueden pasar cosas muy malas. Deberías usar closure. -

@gdoron, ¿puede proporcionarme enlaces relacionados con esa desaprobación? -

3 Respuestas

Prueba esta

function LolClass(){

    var someVar = 0; 
    var self = this;

    this.init = function(){             
        button_a.bind("tap", function(){                
            self.refreshFields(); // now works!
            //refreshFields(); // doesn't work
        });     
    }

    this.refreshFields = function(){
        alert("LOL");
    }

    this.dummy = function(){
        this.refreshFields(); // W O R K S!
    }
}

Respondido el 12 de junio de 12 a las 19:06

Cuando copias su código y lo arreglas, puedes eliminar el "no funciona"... :) - gdoron está apoyando a Monica

Como todas las respuestas son correctas, aceptaré la primera enviada. ¡Gracias! - Marcelo Asís

Deberías almacenar en caché this:

var that = this; // "that" is a convention name for "this"
this.init = function(){             
        button_a.bind("tap", function(){                
            that.refreshFields(); 
        });     
    }

Respondido el 12 de junio de 12 a las 18:06

No conocía esa convención. ¿Dónde puedo encontrar más información al respecto? - Marcelo Asís

@MarceloAssis. Hay mucho que saber, es solo un nombre para el caché this. Aquí hay una pregunta al respecto. - gdoron está apoyando a Monica

Necesitas modificar tu código:

function LolClass(){

    var someVar = 0; 
    var $this = this;

    this.init = function(){             
        button_a.bind("tap", function(){                
            $this.refreshFields();
        });     
    }

    this.refreshFields = function(){
        alert("LOL");
    }

    this.dummy = function(){
        this.refreshFields(); // W O R K S!
    }
}

"esto" dentro de la devolución de llamada se refiere a un objeto diferente. Agregué var $this = this; y usé $ this dentro de la devolución de llamada.

Respondido el 12 de junio de 12 a las 18:06

Cuando copias su código y lo arreglas, puedes eliminar el "no funciona"... :) - gdoron está apoyando a Monica

$this es un mal nombre para this $this generalmente significa $(this). cambiarlo a that or self. - gdoron está apoyando a Monica

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.