2009-06-21 5 views
2

Ich habe mehrere Methoden, die ich im Grunde auf die gleiche Weise in neue Methoden einbinden muss. Meine erste Lösung funktioniert nicht, und ich verstehe warum, aber ich weiß nicht, ob es eine einfache Lösung für dieses Problem gibt oder ob es nicht so funktioniert, wie ich es möchte.Wie kann ich Methoden methodisch in neue Methoden ersetzen?

Hier ist ein Beispiel. Ich habe Objekte a-c, die eine onClick-Methode haben. Ich muss vor den onClick-Methoden etwas Code ausführen. Ich habe versucht, die folgenden:

// objects a-c 
a = {onClick : function() { console.log('a'); }}; 
b = {onClick : function() { console.log('b'); }}; 
c = {onClick : function() { console.log('c'); }}; 

// first try 
var arr = [a, b, c] 
for (var i = 0; i < arr.length; i++) { 
    var oldOnClick = arr[i].onClick; 
    arr[i].onClick = function() { 
     // new code here 
     oldOnClick(); 
    } 
} 

// outputs 'c' 
// what i want is to maintain a reference to the original method 
// so in this case, execute my new code and output 'a' 
a.onClick(); 

Das funktioniert nicht, weil, wenn die neue Methode aufgerufen wird, oldOnClick dem Verfahren aus der letzten Iteration und nicht die zu Verfahren zeigen wird, wenn es zugewiesen wurde.

Gibt es eine einfache Lösung, die ich übersehen habe?

Antwort

3

Was Sie brauchen, ist Schließung:

for(var i=0, l=arr.length; i<l; i++){ 
(function(i){ 
    var oldOnclick = arr[i].onClick; 
    //etc. 
})(i); 
} 
+0

ahh .. ja b/c, die sofort ausgeführt werden. thx, ich dachte, es gäbe eine einfache lösung. :) –

+0

+1 für die Schließung Verwendung – dfa

1

Javascript verbindliche Regeln sind ziemlich seltsam. Wirklich, Javascript ist ziemlich merkwürdig.

Ich weiß nicht, dass ich diese die Weise nennen würde, um es zu beheben, aber durch die Einführung einer Unterfunktion können Sie eine andere Bindung einführen und dadurch dieses bestimmte Problem beheben.

Ihr (modifizierter für Schnell y Chrome Hacking) Code wird:

a = {onClick : function() { alert('a'); }}; 
b = {onClick : function() { alert('b'); }}; 
c = {onClick : function() { alert('c'); }}; 

var arr = [a, b, c] 
for (var i = 0; i < arr.length; i++) { 
    var oldOnClick = arr[i].onClick; 
    arr[i].onClick = bind(oldOnClick); 
} 

a.onClick(); 
b.onClick(); 
c.onClick(); 

function bind(oldFunc) 
{ 
    return function() { 
     //New Code 
     oldFunc(); 
    } 
} 

Der obige Code wirft drei Warnungen: a, b, c. Alles, was "// New Code" ersetzt, wird zur richtigen Zeit ausgeführt.

1

haben Sie versucht mit einigen AOP framwork für Javascript?

zum Beispiel mit jQuery AOP-Plugin:

jQuery.aop.before({target: String, method: 'replace'}, 
    function(regex, newString) { 
    alert("About to replace string '" + this + "' with '" + newString + 
      "' using regEx '" + regex + "'"); 
    } 
); 

auch zu prüfen here.

+0

danke. Ich brauche irgendwann AOP-Framework. –

0
var a = {onClick : function() { console.log('a'); }}; 
var b = {onClick : function() { console.log('b'); }}; 
var c = {onClick : function() { console.log('c'); }}; 

var arr = [a, b, c]; 
for (var i = 0; i < arr.length; i++) { 
    var oldOnClick = arr[i].onClick; 
    arr[i].onClick = wrapHandler(oldOnClick); 
} 

function wrapHandler(handler) { 
    return function() { 
     console.log("New stuff"); 
     handler(); 
    } 
} 

a.onClick(); // outputs "New stuff" then "a" 
b.onClick(); // outputs "New stuff" then "b" 
b.onClick(); // outputs "New stuff" then "c" 
Verwandte Themen