2011-12-07 8 views
6

Czy można powiązać funkcję z inną funkcją przy wywołaniu? Na przykład może to wyglądać mniej więcej tak:Zdarzenie wywoływane funkcji w JS?

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

Tak więc, gdy zostanie wywołane b, a jest również automatycznie wywoływana.


EDYCJA: OK, aby wyjaśnić, nie jest to pytanie dotyczące łańcucha. Chodzi o to, aby znaleźć elegancki sposób na wiązanie zdarzeń. Przestrzegaj normalnego "nie-eleganckiego" sposobu z normalnym oddzwonieniem:

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

To działa poprawnie? Ale co, jeśli mam dzwoniącego wszędzie? Trudno organizować lub zmieniać rzeczy.

Teraz obserwuj najlepsze rozwiązanie! (Jeśli taki istnieje)

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); 

Tak bardzo przypomina normalną rejestrację zdarzeń HTML - JQuery. Nie piszesz na każdym obrazku, na który użytkownik może kliknąć (w każdym miejscu), byłoby to zbyt kłopotliwe, aby to zorganizować! Po prostu napisz jedną prostą jednostkę dla całej witryny. To jest jist tego, czego szukam, z wyjątkiem funkcji JS.

Mam nadzieję, że to wyjaśni.


EDYCJA 2: Potrzeba pracy z IE7 !!! JavaScript 1.8.5 jest świetny i ma wszystko, ale teraz nic go nie obsługuje.

+0

możliwe duplikat (http://stackoverflow.com/questions/3406467/can-i-intercept-a-function-called-directly) –

+0

@AndyE Mam wrażenie, że OP jest bardziej zainteresowany rozwiązaniem automatycznego wywoływania funkcji po kolei. – Peter

+0

@Peter: Nie jestem tego taki pewien. * "Więc kiedy b jest wywoływane, a jest również automatycznie wywoływane." * - istnieje potencjalnie różnica w kolejności wykonywania (to pytanie może na przykład wywołać 'a' po' b'), ale przesłanka między tymi dwoma pytania wydają się być takie same; * "gdy wywoływana jest funkcja, wywołaj tę inną funkcję" *. Mogę się mylić, ale to OP musi wyraźnie rozróżnić te dwa pytania :-) –

Odpowiedz

2

Istnieją różne rozwiązania w zależności od tego, ile chcesz zaprojektować. Proste i elastyczne podejście jest stworzenie łańcuchowy funkcję użytkową:

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](); 
     } 
    } 
} 

Co to robi powraca nową funkcję, która będzie wywoływać funkcje przewidziane w sekwencji.Używaj go tak: [? Mogę przejąć funkcję o nazwie bezpośrednio]

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

Witaj Peter, to rozwiązanie jest dobre do łączenia, ale nie jest użyteczne w sytuacji, w której aktualnie się znajduję. – Bill

+0

@YongkeBillYu: Właściwie to rozwiązuje twój problem. Po prostu wykonaj 'caller1 = chain (handler, caller1)' – hugomg

+0

Tak, masz rację, w rzeczywistości jest to naprawdę dobre rozwiązanie. – Bill

0

JavaScript 1.8.5/ECMAScript 5 rzeczywiście określić bind function, ale nie robi tego, co można opisać powyżej; pozwala określić, co będzie kontekstem, gdy zostanie wywołany, i opcjonalnie, pozwoli ci na zakodowanie określonych argumentów-curry.

+0

Podejrzewam, że obecnie niewiele jest obsługi przeglądarki dla JS 1.8.5, prawda? – Bill

4

Możesz to zrobić z podejściem aspektowym. Oto prosty przykład:

Zamocować wywołanie() funkcjonować b():

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

Teraz nazywamy b():

b(); 

Zobacz go w akcji tutaj: http://jsfiddle.net/eZ9wJ/

+0

W tym przykładzie b jest zmienną globalną. Powinieneś zawsze używać 'var' do definiowania zmiennych; –

+2

Nadpisuję odwołanie do globalnej funkcji b(), którą Yongke już zdefiniował w kodzie w swoim pytaniu. Aby wywołać funkcję a() przy dowolnym wywołaniu funkcji b(), należy nadpisać ją w tym samym zakresie, w którym została zdefiniowana pierwotna funkcja. Oczywiście jest to tylko uproszczony przykład. W prawdziwym przykładzie nie polecałbym definiowania funkcji w zasięgu globalnym. – Simon

+2

Należy pamiętać o tym, że każdy obiekt, który zawierał odwołanie do "b", nie zostanie zaktualizowany; w związku z tym to podejście może się złamać. Należy podkreślić, że wciąż nazywamy tutaj funkcję * new *, mimo że przechowujemy ją w oryginalnej zmiennej. – Peter

Powiązane problemy