首页 > 解决方案 > 如何知道函数调用了多少次而不在函数外部声明变量

问题描述

这是示例函数,我想知道它在函数内部调用了多少次,而不在函数外部声明变量。实际上,当我调用父级时,它是嵌套函数,外部函数被重新声明。我想避免它。

如果现代 javascript 中有一些东西,我们可以从中得到它被调用的次数。

fn(){
}

fn()

标签: javascriptfunction

解决方案


JavaScript 中没有任何内容可以告诉您函数被调用了多少次。如果您想要该信息,则必须将其存储在函数调用期间持续存在的某个位置——例如,函数外部的变量,或类似的。

如果可能的话,专门为此目的在函数之外的变量将是最佳实践,但是您已经说过您不想要一个(或不能拥有一个),因此一种非常不理想的方法是将信息存储在函数本身。函数是对象,这意味着您可以向它们添加属性:

function fn() {
    fn.callCount = (fn.callCount || 0) + 1;
    // ...
}

在函数内部,它的名称作为标识符在范围内,指代函数。所以上面的代码callCount从函数中获取一个属性的值(0如果它不存在或有一个假值,则默认为),然后将该属性设置为该值加一。

这只会计算该函数被调用的次数。你说你的函数是嵌套的。从您的问题中,我无法判断您是想知道对该函数的调用,还是对由调用父函数创建的该版本的函数的调用。上面给你后者。如果你想要前者,你可以将信息存储在父函数中:

function parent() {
    function fn() {
        parent.fnCallCount = (parent.fnCallCount.callCount || 0) + 1;
        // ...
    }
    // ...
}

但同样,如果你能避免它,我不推荐它。如果可以,请使用专用变量。

活生生的例子:

function parent1() {
    function fn() {
        fn.callCount = (fn.callCount || 0) + 1;
        // ...
        console.log(`fn calls so far: ${fn.callCount}`);
    }
    fn();
    fn();
    fn();
}

console.log("Tracking on fn itself:");
parent1();
// fn calls so far: 1
// fn calls so far: 2
// fn calls so far: 3
parent1();
// fn calls so far: 1
// fn calls so far: 2
// fn calls so far: 3

function parent2() {
    function fn() {
        parent2.fnCallCount = (parent2.fnCallCount || 0) + 1;
        // ...
        console.log(`fn calls so far: ${parent2.fnCallCount}`);
    }
    fn();
    fn();
    fn();
}

console.log();
console.log("Tracking on the parent itself:");
parent2();
// fn calls so far: 1
// fn calls so far: 2
// fn calls so far: 3
parent2();
// fn calls so far: 5
// fn calls so far: 4
// fn calls so far: 6
.as-console-wrapper {
    max-height: 100% !important;
}

使用变量(我意识到你说过你不想或不能,但对于其他人,作为替代......):

function parent1() {
    let fnCallsInner = 0;
    function fn() {
        ++fnCallsInner;
        // ...
        console.log(`fn calls so far: ${fnCallsInner}`);
    }
    fn();
    fn();
    fn();
}

console.log("Tracking on fn itself:");
parent1();
// fn calls so far: 1
// fn calls so far: 2
// fn calls so far: 3
parent1();
// fn calls so far: 1
// fn calls so far: 2
// fn calls so far: 3

let fnCallsOuter = 0;
function parent2() {
    function fn() {
        ++fnCallsOuter;
        // ...
        console.log(`fn calls so far: ${fnCallsOuter}`);
    }
    fn();
    fn();
    fn();
}

console.log();
console.log("Tracking on the parent itself:");
parent2();
// fn calls so far: 1
// fn calls so far: 2
// fn calls so far: 3
parent2();
// fn calls so far: 5
// fn calls so far: 4
// fn calls so far: 6
.as-console-wrapper {
    max-height: 100% !important;
}


推荐阅读