2

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

Felix Kling
820k181 gold badges1.1k silver badges1.2k bronze badges
asked Jul 22, 2010 at 8:01

2 Answers 2

1
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.

Kevin Fegan
1,3001 gold badge17 silver badges29 bronze badges
answered Jul 22, 2010 at 8:20
Sign up to request clarification or add additional context in comments.

1 Comment

thanks! but just a point, it won't work the right way is: window[i] = function(x) { return function() { alert(x); return window['original' + x].apply(null, arguments); } }(i);
0

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();
answered Jul 22, 2010 at 8:35

2 Comments

oldMethod.apply(object, arguments); should also return value
why not .apply(this, arguments) for both functions? sometimes those functions might not be called in the objects context.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.