Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to wrap all JavaScript methods with a function?

I want to wrap every function call with some logging code. Something that would produce output like:

func1(param1, param2)
func2(param1)
func3()
func4(param1, param2)

Ideally, I would like an API of the form:

function globalBefore(func);
function globalAfter(func);

I've googled quite a bit for this, but it seems like there's only aspect-oriented solutions that require you to wrap the specific functions you want to log, or whatever. I want something that applies to every function in the global scope (except itself, obviously).

like image 670
blake8086 Avatar asked Oct 12 '10 21:10

blake8086


People also ask

How do you wrap a function in JavaScript?

wrap() is used to wrap a function inside other function. It means that the first calling function (a function which is calling another function in its body) is called and then the called function is being executed. If the calling function does not call the called function then the second function will not be executed.

Which can be used to wrap a function with another function?

Decorators allow us to wrap another function in order to extend the behavior of the wrapped function, without permanently modifying it. In Decorators, functions are taken as the argument into another function and then called inside the wrapper function. Let's see the below examples for better understanding.

What is the reason for wrapping the entire content of a JavaScript code in a function block?

The purpose of wrapping is to a namespace and control the visibility of member functions. It wraps the code inside a function scope and decreases clashing with other libraries.

How do you create a wrapper in JavaScript?

Wrapper specification. Once you are set with the file name for your wrappers, you can start coding. The basic structure of the file is: (function() { // definition of common functions used by the wrappers bellow var wrappers = [ { // wrapping object 1 }, { // wrapping object 2 }, ...


2 Answers

A simple approach would be something like this

var functionPool = {} // create a variable to hold the original versions of the functions

for( var func in window ) // scan all items in window scope
{
  if (typeof(window[func]) === 'function') // if item is a function
  {
    functionPool[func] = window[func]; // store the original to our global pool
    (function(){ // create an closure to maintain function name
         var functionName = func;
         window[functionName] = function(){ // overwrite the function with our own version
         var args = [].splice.call(arguments,0); // convert arguments to array
         // do the logging before callling the method
         console.log('logging: ' + functionName + '('+args.join(',')+')');
         // call the original method but in the window scope, and return the results
         return functionPool[functionName].apply(window, args );
         // additional logging could take place here if we stored the return value ..
        }
      })();
  }
}

To undo you would need to run the

for (func in functionPool)
  window[func] = functionPool[func];

Notes
This handles only global functions, but you can easily extend it to handle specific objects or methods etc..

like image 192
Gabriele Petrioli Avatar answered Sep 22 '22 15:09

Gabriele Petrioli


jquery-aop might do the trick?

like image 24
Nils Weinander Avatar answered Sep 22 '22 15:09

Nils Weinander