如何找出使用 javascript/jquery 调用函数的次数?

Posted

技术标签:

【中文标题】如何找出使用 javascript/jquery 调用函数的次数?【英文标题】:How do I find out how many times a function is called with javascript/jquery? 【发布时间】:2022-01-22 10:57:54 【问题描述】:

也许是一个奇怪的问题,但它是这样的:我有一个定期调用的函数,在该函数中我需要知道我在哪个迭代中,或者该函数被调用了多少次。问题的简化版本:

jQuery( document ).ready( function()
    setInterval( "myFunction()", 3000 );
);

function myFunction()

    alert( "I have been called X times" );

那么,我如何找出上面代码中的 X 呢?

【问题讨论】:

【参考方案1】:

简单版:创建一个像codeling's answer 一样的全局变量。问题 - 如果其他一些代码也定义了一个同名的全局变量,那么你们俩都有麻烦了。

简单的扩展版本 - 给变量一个没人会使用的疯狂名称:calledTimesED7E69A7B141457CA8908A612E3D7A3A

聪明的版本:将该变量附加到现有的全局变量。记住 - 一切都是 javascript 中的对象!

$(function() setInterval(myFunction, 3000); );

function myFunction()

    myFunction.calledTimes++;
    alert( "I have been called " + myFunction.calledTimes + " times" );

myFunction.calledTimes = 0;

传统版本:使用范围来隐藏该变量。

$(function()

    var calledTimes = 0;
    setInterval(function()
    
        calledTimes++;
        alert( "I have been called " + calledTimes + " times" );
    , 3000); 
);

虽然这隐藏了“myFunction”,所以让我们用一种棘手的范围再试一次:

var myFunction = null;
(function()

    var calledTimes = 0;
    myFunction = function()
    
        calledTimes++;
        alert( "I have been called " + calledTimes + " times" );
     
)();

$(function ()  setInterval(myFunction, 3000); );

... 还有无数种其他方法可以通过作用域来隐藏该变量。选择你最喜欢的。

【讨论】:

人们在这里回答问题所花费的时间和精力仍然让我感到惊讶。如果我可以将这个答案投票一千次,我会:) 感谢您提供广泛但简单解释的答案!【参考方案2】:

您可以简单地使用一个全局变量,每次调用该函数时该变量都会增加:

var myFuncCalls = 0;

function myFunction()

    myFuncCalls++;
    alert( "I have been called " + myFuncCalls + " times" );

一旦您的代码变得有点复杂(或者如果您使用许多其他库),您应该考虑使用此处其他答案中所示的范围(最好在 one by Vilx 中解释)。

【讨论】:

即使该函数位于单独的文件中,这也能工作吗?该函数是否具有 myFunCalls 变量的“知识”? 在这种情况下,最好在单独的文件中声明变量,它将在“主”文档中可见。我不是 100% 确定反过来 是的,所有的 javascript 文件在执行之前都在主文档中进行了“复制粘贴”。因此它们都共享相同的全局变量和所有内容。这就是为什么在创建全局变量时要始终小心的原因 - 如果两个脚本创建了相同的全局变量,它们会相互影响工作。 是的。不过在这种情况下不是问题。 @FoadFarkhondeh 你应该非常小心这样的解决方案,因为全局命名空间污染通常是一种不好的做法。【参考方案3】:

这是另一个不使用外部变量的有趣解决方案。最好的部分是您可以保持任何预先存在的功能不变,并像往常一样调用它们。这意味着如果您尝试“利用”现有库中的函数,这对您来说非常有用。它增加了一个unobtrusive计数器,让你可以继续正常调用现有的函数;即使有争论!

// no js library required

// pre-existing function
var a = function()
    console.log("pre-existing function function");
    console.log("arguments:", arguments);
;

// add counter func
var addFnCounter = function(target)
    var swap = target;
    var count = 0;
    return function()
        swap.apply(null, arguments);
        count++;
        console.log("func has been called " + count + " times");
        console.log("\n");
    ;
;

// usage
a = addFnCounter(a);

// call a() as you would normally
a();
a(1,2,3);
a('hello', 'world');

// using your setInterval example
setInterval(a, 3000);

输出

pre-existing function function
arguments: []
func has been called 1 times

pre-existing function function
arguments: [1, 2, 3]
func has been called 2 times

pre-existing function function
arguments: ["hello", "world"]
func has been called 3 times

setInterval 输出

pre-existing function function
arguments: []
func has been called 4 times

pre-existing function function
arguments: []
func has been called 5 times

pre-existing function function
arguments: []
func has been called 6 times

See it working here on jsfiddle

【讨论】:

对于任何想知道的人来说,一个函数接受另一个函数并返回一个修改后的版本被称为 装饰器【参考方案4】:

您必须使用闭包。 通常你会使用一个静态变量。在 Javascript 中,它看起来像:

jQuery( document ).ready( function()
    setInterval( myFunction, 3000 );
);

var myFunction = (function()
    var count = 0;
    return function()
         count++
         alert( "I have been called " + count + " times");
    
)();

演示:http://jsfiddle.net/MZQ83/2/

【讨论】:

【参考方案5】:

与其他答案中的闭包或装饰器相比,静态变量更干净,也不会污染您的外部范围。

var foo = function()
    alert( ++foo.count || (foo.count = 1) );



// test
function callTwice(f) f(); f(); 
callTwice(foo)                  // will alert 1 then 2

callTwice( function bar()           
    alert( ++bar.count || (bar.count = 1) );
);                             // will alert 1 then 2

第二个是一个命名的匿名函数。请注意以下语法:

var foo = function bar() /* foo === bar in here */ 

【讨论】:

【参考方案6】:

创建一个全局变量并初始化为零。然后在调用 myfunction() 时加一。显示该变量而不是 X

【讨论】:

【参考方案7】:

ES6 / ES2015

您可以使用Proxy 为您的函数使用apply() trap:

const addCounter = fn => 
  let count = 0; // keep count

  //define handler
  const handler = 
    apply() 
      //do something with this counter
      console.log(`I have been called $++count times `); 
      
      return Reflect.apply(...arguments); //call the function normally
    
  
  
  //wrap the function into a proxy that uses the handler and return it
  return new Proxy(fn, handler);


setInterval( addCounter(myFunction), 1000 );


function myFunction()  //sample operation - move an image
  const img = document.querySelector("img");

  let offset = img.offsetLeft + 10;
  if (offset > 100) //return to start
    offset = 0;
    
  img.style.left = `$offsetpx`;
img 
  position: absolute;


.as-console-wrapper 
  max-height: 45px !important;
<img src="https://picsum.photos/150" />

【讨论】:

【参考方案8】:

您可以使用立即调用函数表达式(或 IIFE)围绕计数器函数创建一个闭包。你可以使用 ES6 箭头函数来做到这一点:

const counterFunction = (() => 
  let counter = 0;
  return () => console.log(++counter);
)();

counterFunction();
counterFunction();
counterFunction();

或者用普通的函数表达式:

var counterFunction = (function() 
  var counter = 0;
  return function() 
    console.log(++counter);
  ;
)();

counterFunction();
counterFunction();
counterFunction();

Read more about IIFEsRead more about closures

【讨论】:

【参考方案9】:

JS 中有一个内置函数叫做console.count()

【讨论】:

以上是关于如何找出使用 javascript/jquery 调用函数的次数?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 jquery/javascript 将文本插入 json [重复]

如何使用 JavaScript/JQuery 创建一个简单的地图 [重复]

如何使用 Javascript/jQuery 确定图像是不是已加载?

如何使用 Javascript/jQuery 确定图像是不是已加载?

如何使用 PHP 或 JavaScript/jQuery 禁用地址栏?

Rails如何检测是不是使用javascript / jQuery插入了部分