有没有一种很好的方法来跟踪JavaScript中的被调用函数?目前,我能想到的唯一方法是保持全局数组以存储被调用的函数,并在每个函数内每次调用时将函数名称和参数值附加到数组中。
例如
var functionCalls = [];
var functionIndex = 0;
function func1(param1, param2, ... , paramN) {
...
functionCalls[functionIndex] = [func1, param1, param2, ..., paramN];
functionIndex++;
}
function func2(param1, param2, ... , paramN) {
...
functionCalls[functionIndex] = [func2, param1, param2, ..., paramN];
functionIndex++;
}
有更好的方法吗?谢谢!
答案 0 :(得分:1)
如果您希望对代码进行某种分析,请考虑使用外部工具/库,而不是将其硬编码到应用程序中。
Esprisma's function instrumentation example显示了在运行时注入检测以跟踪函数调用等的可能性。
编辑:阅读你的评论后,解释了这个问题的意图:
您可以创建一个装饰器函数,只需传递范围,函数,参数和ID(稍后再调用)。
// define some function we can use to call functions with that will save
// previous execution parameters so we can repeat previous calls
callFunction = (function() {
var called = {};
function callFunction() {
// turn the arguments associative array into a real array
args = Array.prototype.slice(arguments, 0);
if(args.length == 4) {
// assume we want to call and save the function
runAndSaveFunction.apply(this, args);
}
if(args.length == 1) {
// assume we want to recall a function based off an id
repeatCall.apply(this, args);
}
}
function runAndSaveFunction(context, func, args, id) {
// call the function given a context
func.apply(context, args);
// save the call
called[id] = {
fn: func,
args: args,
ctx: context
};
}
function repeatCall(id) {
var call = called[id];
runAndSaveFunction(call.ctx, call.fn, call.args, id);
}
return callFunction;
})();
然后我们可以使用这个函数:
// this function exists just to call our real function
// below with our instrumentation
function func1() {
callFunction(this, _func1, arguments, 'someId');
}
// we designate the original as a "private" function that
// actually contains the implementation
function _func1(param1, param2, ... , paramN) {
...
}
func1(a, b, c, d, e...);
callFunction('someId'); // recall the previous func1 call
注意:上面的代码中可能存在语法/语言错误;它意味着用作指南
答案 1 :(得分:1)
看起来你可能走错了路,但这是一种方法:
Function.prototype.track = function() {
var fn = this;
return function() {
//do tracking here
console.log(arguments)
return fn.apply(this, arguments);
}
}
//You don't have to make it a method on all functions
//I never add to prototypes of native Objects but it
//does look more elegant for this scenario.
示例:
function sum(a, b) {
return a + b;
}
var sumTracker = sum.track();
var onePlusTwo = sumTracker(1,2)
> [1, 2]
onePlusTwo
> 3