views:

189

answers:

6

Hi all,

I need to decorate a 3rd party function that I can't modify so I will need to decorate it in any way. I found that in Prototype there is something to do it easily [1].

Is there any alternative to that in jQuery or in plain JavaScript?

[1] http://api.prototypejs.org/language/function.html#wrap-instance%5Fmethod

+1  A: 

What about your scenario requires a library? It seems that with native javascript, you could simply:

1) Save a copy of the original function
2) Create a modified version of the function which uses the original
3) Store a reference to the modified version where the original was originally stored.
Frank Schwieterman
What you mean with save a copy of the original?Something like this?<code>new_func = originalFuncfunction myExtendedVersion() { // do my stuff new_func(); // do my stuff}</code>
Esteban Feldman
yeah, then set originalFunc = myExtendedVersion.
Frank Schwieterman
new_func is a confusing name though, I'd call it "originalFunc" (presumably the "originalFunc" in your example is named something else)
Frank Schwieterman
A: 

You may find this article useful.

Li0liQ
A: 

I like the wrap functions provided by libraries: Prototype has the wrap function. In ExtJS, one might use createDelegate or createInterceptor. Dojo has declarative AOP. Sans framework, one might do this:

myFunction(){
   something();
   thirdParty.call();  // or apply
   perhapsSomethingElse();
}
Upper Stage
+1  A: 

With jquery, it would be pretty easy to just add in another function to use. Try something like:

//Sample function you're wrapping around 
function say_hi(){
    alert('hi');
}

//quick jq plugin
jQuery.fn.functionWrap = function(arg,opts){
    if(opts.before && typeof(opts.before)=='function'){
     opts.before();
    }
    arg();
    if(opts.after && typeof(opts.after)=='function'){
     opts.after();
    }
};


//sample function to use the wrapper func
function btnPress(){
    $().functionWrap(
     say_hi,
     {
      before : function(){ alert('happens before'); }, 
      after : function(){ alert('happens after'); } 
     }
    );
}

Try adding that to your page, and something like this to test it out:

<input type="button" value="asdf" onClick="btnPress();" />

Hope this helps you.

Jage
This will do it, thanks. But I found that the accepted answer is clearer.
Esteban Feldman
A: 

I will go for Frank Schwieterman solution:

new_func = originalFunc
function myExtendedVersion()
{ 
  // do my stuff
  new_func();
  // do my stuff 
}
Esteban Feldman
A: 

You could do it with the jquery AOP plugin: http://code.google.com/p/jquery-aop/

Code would look like:

jQuery.aop.around( {target: window, method: 'originalFunc'}, 
  function(invocation) {
    // do your stuff
    invocation.proceed(); 
    // do your stuff
  }
);
gnz