Fernando
Fernando

Reputation: 21

Iterate and change javascript functions on-the-fly

I want to be able to iterate through all JavaScript functions in my document and, for instance, add an alert('ok'); to them.

so if I have:

function a(num) {
  return num;
}

after I run my javascript code and call this function, it will actually do:

{
  alert('ok');
  return num;
}

I know I can access a function using window.[funcName], but how can I iterate thru all functions and edit them?

thanks

PS: I know this is not a very good idea, but it's just for a debug environment

Upvotes: 2

Views: 2173

Answers (2)

Alexey Lebedev
Alexey Lebedev

Reputation: 12197

for (var i in window) {
  if (typeof window[i] == 'function') console.log(i); // logs the function name
}

This gets you a list of functions. You cannot modify functions in JavaScript, you can only wrap them. This means you make a copy of the function and replace the original with a wrapper. Say, we have this function:

function a(num) { return num;}

then we wrap it like this:

functionName = 'a'; // original function name
window['_original_' + functionName] = window[functionName]; // putting it in a safe place
window[functionName] = function() { // creating wrapper
   alert('ok'); //logger function
   return window['_original_' + functionName].apply(null, arguments); //invoke original
}

This gives you only global-space functions, e.g. it won't log jQuery plugins. If you want to log all functions use Firebug's profiler.

Upvotes: 1

Marimuthu Madasamy
Marimuthu Madasamy

Reputation: 13531

Instead of modifying the code of an existing function, I tried using an interceptor function wrapping an existing function. Just a quick implementation (we can improve this further)

function intercept(object, methodBindName, interceptor) {
    var oldMethod = object[methodBindName];
    object[methodBindName] = function() {
        interceptor.apply(null, arguments);
        return oldMethod.apply(object, arguments);
    }
}

function test1(msg) {alert(msg);}
function test2() {alert('hi');}

var methodNames = ['test1', 'test2'];

for(var i = 0; i < methodNames.length; i++) {
    intercept(window, methodNames[i], function(){alert('Hello');})
}
test1('foo');
test2();

Upvotes: 0

Related Questions