Получить список всех функций, которые вызываются другой функцией
В JavaScript возможно ли получить список всех функций, которые вызываются другой функцией? Я хочу создать дерево зависимостей функций, чтобы проанализировать, как функции в скрипте связаны друг с другом (и какие функции требуются для каких других функций).
Например:
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");
}
4 ответа
Эсприма может вам помочь. Это анализатор Javascript, который может помочь вам выполнить статический анализ кода.
Вот быстрый пример ( 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);
Очевидно, что для того, чтобы предложить большую ценность, нужна большая помощь, но это может дать вам некоторое представление о том, что можно и с чего начать.
Интересный вопрос. Я тоже сомневаюсь в мотиве этого... Надеюсь, это просто для отладки или лучшего понимания структуры приложения.
Вот дикая идея: просто бросить это там...
Если бы вы могли связать каждую функцию, вы можете получить вызываемого абонента:
arguments.callee.name
И запишите это в глобальную переменную (возможно, объект, где каждый ключ является именем функции, а значение - массивом имен функций).
По сути, вы не можете.
Объекты / функции не будут знать, что они будут выполнять, пока вы их не выполните, если вы не выполняете регулярные выражения для самого кода функции java-скрипта функции... в лучшем случае ненадежного.
Если вы хотите сделать это задом наперед, отслеживая стек назад, у вопросов, подобных этому, есть решения: как я могу получить трассировку стека Javascript при выдаче исключения?
Чтобы достичь того, что вы, вероятно, ищете, вы можете создать универсальный класс, от которого наследуются ваши функции, с вашим собственным реализованным методом для назначения им вызовов функций.
Очевидный ответ - что-то вроде следующего:
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);
};
Но это на самом деле сразу же входит в бесконечный цикл, потому что сам акт вызова console.log
выполняет вызов функции, которая вызывает console.log, которая выполняет вызов функции, которая вызывает console.log
, который...
ИЛИ ЖЕ
Я предполагаю, что вы хотите отфильтровать нативные функции. В Firefox Function.toString()
возвращает тело функции, которое для нативных функций будет иметь вид:
function addEventListener() {
[native code]
}
Вы могли бы соответствовать шаблону /\[native code\]/
в вашем цикле и опустите соответствующие функции.