Get a list of all functions that are called by another function

梦想的初衷 提交于 2019-12-10 13:41:59

问题


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");
}

回答1:


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.




回答2:


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




回答3:


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.




回答4:


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.



来源:https://stackoverflow.com/questions/15445761/get-a-list-of-all-functions-that-are-called-by-another-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!