문제

In JavaScript, is it possible to obtain a list of all functions that are called by another function? I want to create a tree of function dependencies, to analyze how the functions in a script are related to each other (and which functions are required by which other functions).

For example:

getAllCalledFunctions(funcA); //this should return [funcB, funcC, funcD], since these are the functions that are required by funcA.

function getAllCalledFunctions(functionName){
    //how should I implement this?
}

function funcA(){
    funcB();
    funcC();
}

function funcB(){
    funcD();
}

function funcC(){
    funcD();
}

function funcD(){
    console.log("This function is called by funcC and funcD");
}
도움이 되었습니까?

해결책

Esprima may help you. It is a Javascript parser that can help you do static code analysis.

Here's a quick example (http://jsfiddle.net/fyBvT/):

var code = 'function funcA() { funcB(); funcC(); } function funcB(){ funcD(); } function funcC() { funcD(); } function funcD(){ console.log("This function is called by funcC and funcD"); }';
var syntax = esprima.parse(code);

var funcs = [];
_.each(syntax.body, function(i) {
    if (i.type == 'FunctionDeclaration') {
        var func = {name: i.id.name};

        _.each(i.body.body, function(j) {
            if (j.type == 'ExpressionStatement' && j.expression.type == 'CallExpression') {
                func.calls = func.calls || [];
                func.calls.push(j.expression.callee.name);
            }
        });

        funcs.push(func);
    }
});

console.log(funcs);

Clearly this needs a lot of help to offer much value, but it might give you some idea of what's possible and where to start.

다른 팁

Interesting question. I too question the motive behind it... Hopefully it's just for debugging or understanding the structure of the application better.

Here's a WILD idea: Just throwing it out there...

If you could tie into each function, you can get the callee by:

arguments.callee.name

And write that to a global variable (perhaps an object with each key being the name of the function, and the value being an array of function names).

Basically, you can't.

Objects/Functions won't know what will they execute unless you execute them, Unless you perform regular expressions on the function's java-script code itself.. unreliable at best.

If you want to do it backwards, tracing the stack back, questions like this have solutions: How can I get a Javascript stack trace when I throw an exception?

To achieve what you are probably looking for, You could create a generic class, from which your functions inherit, with your own implemented method to assign function calls to them.

The obvious answer is something like the following:

var origCall = Function.prototype.call;
Function.prototype.call = function (thisArg) {
    console.log("calling a function");

    var args = Array.prototype.slice.call(arguments, 1);
    origCall.apply(thisArg, args);
};

But this actually immediately enters an infinite loop, because the very act of calling console.log executes a function call, which calls console.log, which executes a function call, which calls console.log, which...

OR

I'm assuming you want to filter out native functions. In Firefox, Function.toString() returns the function body, which for native functions, will be in the form:

function addEventListener() { 
    [native code] 
}

You could match the pattern /\[native code\]/ in your loop and omit the functions that match.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top