Javascript 检查是否调用了函数-带或不带参数

Javascript 检查是否调用了函数-带或不带参数,javascript,Javascript,你能告诉我如何写一个函数来检查一个特定的函数是否被调用,调用了多少次-有参数还是没有参数 提前感谢您您可以制作一个函数装饰器,将计数和参数保存在闭包中,类似于: // Helper to convert pseudo-arrays // such as `arguments` to real arrays var __slice = Array.prototype.slice; // Higher-order function that // returns a function that s

你能告诉我如何写一个函数来检查一个特定的函数是否被调用,调用了多少次-有参数还是没有参数


提前感谢您

您可以制作一个函数装饰器,将计数和参数保存在闭包中,类似于:

// Helper to convert pseudo-arrays
// such as `arguments` to real arrays
var __slice = Array.prototype.slice;

// Higher-order function that
// returns a function that saves the count
// and arguments when called
function track(f) {
  var i = 0; // count
  var calls = []; // array to save the info
  var fn = function() {
    // Save arguments and incremented counter
    calls.push({
      count: i++,
      args: __slice.call(arguments)
    });
    // Call the original function with arguments
    // preserving the context, and return its value
    return f.apply(this, arguments);
  };
  // A function, attached to the decorated function,
  // that gets the info out of the closure
  fn.count = function() {
    return calls;
  };
  // Return decorated function to be used
  return fn;
}

// Decorate a normal function
var add1 = track(function(x) {
  return x + 1;
});

// Run the function 3 times
// Internally the decorated function will keep
// track of the count and arguments
add1(1);
add1(2);
add1(3);

// Using the `count` function of our decorated function
console.log(add1.count());
/*^
  [ { count: 0, args: [ 1 ] },
    { count: 1, args: [ 2 ] },
    { count: 2, args: [ 3 ] } ]
*/
track(document, 'getElementById');

每个函数都定义了一个调用者属性。你可以这样做

function callfn() {
        if (callfn.caller == null) {
            return ("The function was called from the top!");
        } else
            return ("This function's caller was " + callfn.caller);
        }
    }
var counter = {};
counter.with_param = 0;
counter.without_param = 0;
function test(arg){
    if(!arg){
        counter.without_param = counter.without_param + 1;
    }else{
        counter.with_param = counter.with_param + 1;
    }
}
test(1);
test(5);
test();
test();
test(6);

console.log('WITH PARAM ' + counter.with_param);//3
console.log('WITHOUT PARAM ' + counter.without_param);//2
console.log('TOTAL CALLING  ' + (counter.with_param + counter.without_param));//5

试试这样的

function callfn() {
        if (callfn.caller == null) {
            return ("The function was called from the top!");
        } else
            return ("This function's caller was " + callfn.caller);
        }
    }
var counter = {};
counter.with_param = 0;
counter.without_param = 0;
function test(arg){
    if(!arg){
        counter.without_param = counter.without_param + 1;
    }else{
        counter.with_param = counter.with_param + 1;
    }
}
test(1);
test(5);
test();
test();
test(6);

console.log('WITH PARAM ' + counter.with_param);//3
console.log('WITHOUT PARAM ' + counter.without_param);//2
console.log('TOTAL CALLING  ' + (counter.with_param + counter.without_param));//5

@elclanrs的解决方案确实不错,但存在多个问题:

  • 您需要调用tracker函数而不是原始函数。这意味着您需要更改一些原始代码才能使用它

  • 您需要存储对跟踪器对象的引用以获取计数

以下是这些问题的解决方案:

function track() {
    var calls = [],
        context = window,
        funcName,
        i = 0;

    if (arguments.length === 1) { 
        context = window;
        funcName = arguments[0];
    } else {
        context = arguments[0];
        funcName = arguments[1];
    }

    var func = context[funcName];
    context[funcName] = function () {
        calls.push({
            count: i++,
            args: Array.prototype.slice.call(arguments)
        });
        return func.apply(context, arguments);
    };
    context[funcName].getCalls = function () { 
        return calls;
    };
}
用法示例:

// The function we want to track.
function log(val) {
    console.log(val);
}

// Start tracking the function
track('log');

// Normal usage of the function
log('Message 1');
log('Message 2');

// Print the collected data of the function
console.log(log.getCalls());
/*^
  [ { count: 0, args: [ 'Message 1' ] },
    { count: 1, args: [ 'Message 2' ] } ]
*/
注意:如果函数不在全局上下文中(例如:
document.getElementById
),则需要执行以下操作:

// Helper to convert pseudo-arrays
// such as `arguments` to real arrays
var __slice = Array.prototype.slice;

// Higher-order function that
// returns a function that saves the count
// and arguments when called
function track(f) {
  var i = 0; // count
  var calls = []; // array to save the info
  var fn = function() {
    // Save arguments and incremented counter
    calls.push({
      count: i++,
      args: __slice.call(arguments)
    });
    // Call the original function with arguments
    // preserving the context, and return its value
    return f.apply(this, arguments);
  };
  // A function, attached to the decorated function,
  // that gets the info out of the closure
  fn.count = function() {
    return calls;
  };
  // Return decorated function to be used
  return fn;
}

// Decorate a normal function
var add1 = track(function(x) {
  return x + 1;
});

// Run the function 3 times
// Internally the decorated function will keep
// track of the count and arguments
add1(1);
add1(2);
add1(3);

// Using the `count` function of our decorated function
console.log(add1.count());
/*^
  [ { count: 0, args: [ 1 ] },
    { count: 1, args: [ 2 ] },
    { count: 2, args: [ 3 ] } ]
*/
track(document, 'getElementById');
然后,您可以正常收集数据:

document.getElementById.getCalls()

您有权访问要跟踪的函数的代码吗?你能改一下吗?编辑好了,看看是否有用。