2011-12-07 7 views
6

¿Es posible vincular una función a otra función en invocación? Por ejemplo, sería algo como esto:Evento invocado por función en JS?

function a(){...} 
function b(){...} 
b.bind("onInvoke","a"); 

Así que cuando se llama a b, a también se llama automáticamente.


EDITAR: OK Aceptar, para aclarar, esto no es una cuestión de encadenamiento. La idea es encontrar una manera elegante de hacer el enlace de eventos. Observe la forma normal de "no elegante" con devolución de llamada de función normal:

function handler(){...} 
function caller1(){handler(); ...} 
function caller2(){handler(); ...} 
function caller2(){handler(); ...} 
// More callers all over your website everywhere else 

Eso funciona ¿verdad? Pero, ¿y si tengo llamadas por todos lados? Es difícil organizar o cambiar cosas.

¡Ahora observe la solución superior! (Si existe)

function handler(){...} 
// Caller make no reference to handler on creation 
function caller1(){...} 
function caller2(){...} 
function caller3(){...} 
// Caller function are still all over the place, all over your website 
// Event handler registered later in one location here, doesn't matter where they are phsically 
caller1.bind("onInvoke",handler); 
caller2.bind("onInvoke",handler); 
caller3.bind("onInvoke",handler); 

Muy parecido al registro normal de un evento HTML - JQuery. No escriba onClick en cada imagen en la que el usuario pueda hacer clic (que están por todas partes), ¡sería demasiado problemático organizar eso! Simplemente escriba uno simple

$("img").bind("onClick",click_handler); 

para todo su sitio. Esta es la cuestión de lo que estoy buscando, a excepción de las funciones de JS.

Espero aclarar las cosas.


EDIT 2: Necesito trabajar con IE7 !!! JavaScript 1.8.5 es genial y todo, pero nada lo soporta en este momento.

+0

posible duplicado de (http://stackoverflow.com/questions/3406467/can-i-intercept-a-function-called-directly) –

+0

@AndyE Me da la sensación de que OP está más interesado en una solución para llamar automáticamente las funciones en secuencia. – Peter

+0

@Peter: No estoy tan seguro. * "Así que cuando se invoca b, a también se llama automáticamente." * - existe una diferencia potencialmente en el orden de ejecución (esta pregunta puede querer invocar 'a' después de' b', por ejemplo), pero la premisa entre los dos las preguntas parecen ser las mismas; * "cuando se llama a una función, llame a esta otra función" *. Podría estar equivocado, pero depende del OP hacer una clara distinción entre las dos preguntas :-) –

Respuesta

2

Existen varias soluciones dependiendo de cuánto desea diseñar. Un enfoque simple y flexible es crear una función de utilidad encadenamiento:

function chain() { 
    var args = arguments; 
    return function() { 
     // loop through arguments and invoke all functions 
     for(var i = 0; i < args.length; i++) { 
     if(typeof args[i] == "function") 
      args[i](); 
     } 
    } 
} 

Lo que esto hace es devolver una nueva función que se llame a las funciones previstas en secuencia.Utilizar de esta manera: [? ¿Puedo interceptar una función llamada directa]

var myChain = chain(b, a); 
myChain(); 
+0

Hola Peter, esta solución es buena para encadenar pero no es útil en la situación en la que me encuentro actualmente. – Bill

+0

@YongkeBillYu: En realidad, resuelve tu problema. Simplemente haz 'caller1 = chain (handler, caller1)' – hugomg

+0

Sí, tienes razón, en realidad es una solución realmente buena. – Bill

0

JavaScript 1.8.5/ECMAScript 5 en efecto, definen un bind function, pero no hace lo que usted describe más arriba; le permite especificar cuál será el contexto this cuando se invoca y, opcionalmente, le permite codificar ciertos argumentos-curry.

+0

Supongo que no existe mucho soporte de navegador actualmente para JS 1.8.5 ¿verdad? – Bill

4

Puede hacerlo con un enfoque orientado a aspectos. Aquí está un ejemplo sencillo:

Attach llamada a un() a función B():

var _b = b; 
b = function(){ 
    _b(); 
    a(); 
} 

Ahora llame b():

b(); 

verlo en acción aquí: http://jsfiddle.net/eZ9wJ/

+0

En este ejemplo, b es una variable global. Deberías usar siempre 'var' para definir variables; –

+2

Estoy sobrescribiendo la referencia a la función global b() que Yongke ya definió en el código en su pregunta. Para invocar la función a() en cualquier llamada a b(), debe sobreescribirla en el mismo ámbito en el que se ha definido la función original. Por supuesto, esto es solo un ejemplo simplificado. En un ejemplo real, no recomendaría definir la función en el alcance global. – Simon

+2

Una cosa a tener en cuenta aquí es que ningún objeto que inicialmente se aferra a una referencia a 'b' no se actualizará; por lo tanto, este enfoque podría romperse. Debe enfatizarse que todavía estamos llamando a una función * nueva * aquí, aunque la almacenemos en la variable original. – Peter

Cuestiones relacionadas