0

I'm working on some JS where functions are passed around by reference, and it's difficult to see which function is being called at times. It will be passed around through 7-8 functions each with a ton of parameters, so it's very time consuming to track back where it came from. I'm working on changing a bit of this, but the only way I've been able to figure out to see which function is actually being called it is to do something like this:

        if (console && console.log && method.toSource) {
            console.log(method.toSource());
        }

This only works in FF but at least then I can search for the source of the called function. Is there a better way?

Shawn
  • 19,465
  • 20
  • 98
  • 152
  • Why do you have to know which function is passed? Because of the parameters? To me it looks like you should change your design. Being flexible on one side but having to know which concrete instance you are dealing with does not seem to fit together. Could you elaborate more on the context? Or is it just for debugging? – Felix Kling Mar 14 '11 at 19:58
  • 1
    For me, if I do `console.log(myFunction)` and then click on the output in the console, it jumps me straight to the function in the Script tab. – nickf Mar 14 '11 at 19:59
  • @felix Here's an example. There's an issue occurring when I select some item from a list of items. I need to find the function that's called when the item is selected and see what is going on in there. It will just look like onclick(). Obv I can find out where that method is set, but sometimes it takes a long time because that itself might have been a passed function. The codebase is massive, so I need an quick automated way of finding it, instead of looking around manually. – Shawn Mar 14 '11 at 20:06

4 Answers4

1

Try this

var whee = {
    test: function(ab) {
        console.log(ab);
        this.test2('Hello', 'World');
    },

    test2: function(a, b) {
        console.log(a+' '+b);
    }
};

function augment(obj, withFn) {
    var name, fn;
    for (name in obj) {
        fn = obj[name];
        if (typeof fn === 'function') {
            obj[name] = (function(name, fn) {
                var args = arguments;
                return function() {
                    withFn.apply(this, args);
                    fn.apply(this, arguments);
                }
            })(name, fn);
        }
    }
}

augment(whee, function(name, fn) {
    console.log("calling " + name);
});

whee.test('hi');

the function augment takes an obj as the first parameter and a function as the second. It loops through all the members of the object looking for functions. When it finds one it replaces it with a function that calls the passed in function and then the original function. I stole almost all of the code from this stackoverflow answer.

It doesn't seem to play nicely when you pass it the window object so hopefully your functions are not all declared in the window scope.

There is also this answer in which they try to override the Function.prototype.call function with their own. I couldn't get it to work in Firefox but maybe you will have better luck.

Community
  • 1
  • 1
  • That only works if he already has a couple of ideas of which function it might be. – Jamie Wong Mar 14 '11 at 20:01
  • It does look like firebug has a call logging tab. I've never used it but it might work for you. http://getfirebug.com/javascript –  Mar 14 '11 at 20:18
  • would this work for you? http://stackoverflow.com/questions/5033836/adding-console-log-to-every-function-automatically basically they loop through all the top level functions and replace them with a wrapper function. –  Mar 14 '11 at 20:33
1

install firefox
install firebug addon
click on the bug icon on the lower right
click on script tab
click enable
reload page
click on stack tab on right panel in firebug

The_asMan
  • 6,364
  • 4
  • 23
  • 34
1

Have you tried console.trace() in Firebug?

user123444555621
  • 148,182
  • 27
  • 114
  • 126
1

Functions can be compared by reference, so if you have a dictionary like in Alex Brown's answer:

var whee = {
    test: function(ab) {
        console.log(ab);
        this.test2('Hello', 'World');
    },

    test2: function(a, b) {
        console.log(a+' '+b);
    }
};

then you can just compare your now-anonymous reference with each:

function whichFunc(func, funcDict) {
    for (var funcname in funcDict) {
        if (func == funcDict[funcname]) {
            return funcname;
        }
    }
}

Pretty simple.

Phil H
  • 19,928
  • 7
  • 68
  • 105