Wie kann ich (wrap) Methoden in neuen Methoden programmatisch ersetzen?
-
06-07-2019 - |
Frage
Ich habe mehrere Methoden, die ich grundsätzlich auf die gleiche Art und Weise in neuen Methoden wickeln müssen. Meine erste Lösung nicht funktioniert, und ich verstehe, warum, aber ich weiß nicht, ob es eine einfache Lösung für dieses Problem ist, oder wenn es nicht die Art und Weise getan werden kann, was ich will, es zu tun.
Hier ist ein Beispiel. Ich habe Objekte a-c, die eine onClick Methode haben. Ich brauche einige Code vor den onClick Methoden auszufü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 des Verfahren aus der letzten Iteration und nicht die zu Verfahren zeigen wird, wenn es zugewiesen wurde.
Gibt es eine einfache Lösung, die ich mit Blick auf?
Lösung
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);
}
Andere Tipps
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 + "'");
}
);
überprüfen auch hier .
Javascript verbindliche Regeln sind ziemlich seltsam. Wirklich, Javascript ist ziemlich seltsam.
Ich weiß nicht, dass ich das nennen würde die Art und Weise, es zu beheben, sondern durch eine Unterfunktion der Einführung können Sie einen anderen binden bekommen einführen und damit dieses besondere Problem beheben.
Ihre (modifiziert für quick-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 ‚// Neuen Code‘ ersetzt wird zur richtigen Zeit ausgeführt werden.
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"