bind() y bindAsEventListener() en Prototype, como utilizarlos
Desde que empecé a trabajar mi función principal es la de desarrollador web. Básicamente me peleo todo el dÃa con Prototype y con AJAX. Después de unas cuantas semana Prototype se ha convertido en parte en un gran aliado, pero también en un enemigo a batir. Conocer el framework con profundidad es esencial para trabajar con él y a veces no es fácil. Una de las cosas que mas trabajo me costó entender fue la utilidad de las funciones bind() y bindAsEventListener(). Ambas son muy potentes y muy útiles cuando se utilizan bien, pero comprender su uso puede ser difÃcil y a veces nos pueden dar quebraderos de cabeza.
Voy a intentar explicar de forma clara y simple como se usan estas dos funciones y para qué sirven. Vayamos por partes.
bind(): Es una de las estrellas en Prototype y también es una de las más trabajo suele costar entender. Imaginemos un objeto que tiene métodos para acceder a sus datos miembro. Usandobind()podemos hacer que esos objetos accedan a datos miembro de otros objetos en lugar de a los del objeto original. Veamos un ejemplo:-
-
var Clase1 = Class.create({
-
initialize: function(msg){
-
this.mensaje = msg;
-
},
-
log: function(){
-
console.log(this.mensaje);
-
}
-
});
-
var objeto1 = new Clase1("Mensaje, Objeto1");
-
var objeto2 = new Clase1("Mensaje, Objeto2");
-
-
objeto1.log(); //Genera -> Mensaje, Objeto1
-
objeto2.log(); //Genera -> Mensaje, Objeto2
-
//Creamos el bind de alerta para que se ejecute en el
-
//contexto del objeto2.
-
var log_bind = objeto1.log.bind(objeto2);
-
log_bind(); //Genera -> Mensaje, Objeto2
Como vemos, la llamada a
log_bind()realiza la llamada aobjeto1.bind()usando el contexto delobjeto2, lo cual en terminos prácticos equivale a hacerobjeto2.bind()También podemos usar
bind()para añadir argumentos a la llamada a una función. Veamos un ejemplo de esto.-
var Clase2 = Class.create({
-
initialize: function(msg){
-
this.mensaje = msg;
-
},
-
log: function(){
-
console.log(this.mensaje + ‘ ‘ + $A(arguments).join(‘, ‘));
-
}
-
});
-
-
var objeto3 = new Clase2("Mensaje, Objeto3");
-
objeto3.log();
-
var log_bind_mas_argumentos = objeto3.log.bind(objeto3,1,2,3,4,‘ lo que sea’);
-
log_bind_mas_argumentos();
Esta vez no cambiamos el contexto de la función, pero añadimos varios argumentos extra que luego se extraen usando
$A(arguments), convirtiéndolos asà en un Array de Prototype.-
bindAsEventListener(): Una vez hemos comprendido el uso que tienebind()es fácil entender la dinámica debindAsEventListener(). Su funcionamiento es el mismo que el de la funciónbind()pero con adaptaciones especÃficas para un contexto concreto, el de la captura de eventos.Este es el mismo ejemplo que hay en el API de Prototype pero un poco retocado:-
var obj = {
-
name: ‘Un bonito ejemplo’
-
};
-
-
function handler(evento){
-
var tag = Event.element(evento).tagName.toLowerCase();
-
var data = $A(arguments);
-
data.shift();
-
console.log(this.name + ‘\nHas clickado en ‘ + tag + ‘\nOtros argumentos: ‘ + data.join(‘, ‘));
-
}
-
$(‘elemento’).observe(‘click’, handler.bindAsEventListener(obj, 1, 2, 3));
Por partes, el objeto
objtiene una propiedadnamey la funciónhandler(evento)se encarga de manejar el evento una vez se ha disparado. Esta función extrae el nombre del elemento de la página que ha disparado el evento, los argumentos extra pasados a la función y los muestra todos por la consola de facebook. La clave de todo el ejemplo es la lÃnea:-
$(‘elemento’).observe(‘click’, handler.bindAsEventListener(obj, 1, 2, 3));
Esta lÃnea asigna la función
handler(evento)como manejadora del eventoonclickdel elemento y además cambia su contexto al del objetoobjy le pasa 3 números como argumento. Pero echando un segundo vistazo a la función vemos que en ningún momento le pasamos el argumentoevento. Esa es precisamente la función especial debindAsEventListener()pasar como primer argumento el objeto de la clase Event que representa al evento que se ha disparado.Usando bindAsEventListener() siempre recibiremos el objeto Event como primer argumento, sin necesidad de pasar ese evento de forma manual.
-
Espero que después de este par de ejemplo quede todo un poco más claro, como siempre se aceptan preguntas, dudas y sugerencias
y para todo el código que necesitéis pegar podéis usar Pastie
No hay posts relacionados.


Octubre 13th, 2008 at 0:14
Información Bitacoras.com…
Si lo deseas, puedes hacer click para valorar este post en Bitacoras.com. Gracias….
Octubre 15th, 2008 at 10:36
Algo que guardar y consultar en un futuro, gracias máquina…
Julio 6th, 2009 at 14:19
esta buenÃsimo el artÃculo, me parece que casi lo entiendo, pero aún tengo un par de dudas, será q puedes aclarármelas??la primera y más importante, a q te refieres con cambiar el contexto del objeto/función, q significa esto??
hasta donde vi, parece algo asà como hacer herencia.
por otro lado, hara hacer esto, si o si es necesario pasarle un objeto/función como primer parámetro??
para usar el observe y poder pasar parámetros a la función, creo q siempre es necesario usar el bindAsEventListener verdad???
y por último, q restricciones se tienen para poder usar estas funciones??
muchas gracias por tu post, es de mucha ayuda.
salu2
Julio 6th, 2009 at 15:09
@naitsir:
Cambiar el contexto significa hacer que un método de una instancia se ejecute en una instancia distinta, en lugar del objeto original. En javascript el contexto de los métodos es siempre el mismo por lo que es útil poder cambiar el contexto y forzar que sea el que nosotros queramos.
Con respecto al uso de bindAsEventListener, no es necesario. Puedes usar otras herramientas de prototype, mira la página correspondiente del API http://www.prototypejs.org/api/function . El sentido de bindAsEventListener es asegurarse que el primer argumento al capturar un evento es el objeto que contiene los datos del evento en sÃ.
Las limitaciones… bueno, no se me ocurren, lo que no significa que no existan. Depende del uso que se le de y de lo que quieras hacer o necesites.
Un saludo y muchas gracias a ti por tu comentario
Julio 10th, 2009 at 18:19
Hola,
necesito hacerte una consulta:
utilizo este codigo:
Event.observe(’imgTest’, ‘click’, function(event) {
fxAlgo();
});
Mi pregunta es:
como hago para poder conocer que funcion tiene asignado el elemento ‘imgTest’ para el evento click? es decir obtener como resultado fxAlgo();
Nota:
anteriormente, utilizaba el evento onclick en la etiqueta:
y haciendo luego: $(’imgTest’).onclick
obtenia:
function onclick(event) {
fxAlgo();
}
Julio 10th, 2009 at 20:12
siento responder tan tarde, muchas gracias por la explicación, en verdad me iluminaste… es un quebradero de cabeza esta función, o al menos eso pensaba hasta q leà tu artÃculo. seguà asÃ!
salu2
Julio 13th, 2009 at 16:00
No existe un método para recuperar esa función (al menos no se me ocurre ninguna), entre otras cosas por que puedes tener varias funciones asignadas. Lo mejor que puedes hacer para solucionar tu problema es almacenar anteriormente esa función en un objeto o de alguna otra forma que te resulte conveniente.
Un saludo.
Julio 13th, 2009 at 16:56
Gracias por responder, sabiendo que no se puede recuperar, voy a guardarlo en un array. slds.
Noviembre 29th, 2009 at 0:04
oO’ ¿Facebook?
No sé si me he perdido algo pero me imagino que querrÃas decir Firebug, ¿no?
Se agradecen artÃculos en español sobre Prototype, y la cuestión es que algunos nos acostumbramos demasiado a librerÃas facilonas olvidando la madre del cordero: JavaScript a pelo y DOM (en este caso eventos); de ahà estas dudas me temo.