Abhinash Majhi
Abhinash Majhi

Reputation: 507

How to know How many times function is called without declaring variable outside function

This is the sample function I want to know how many times it is called inside the function without declaring variable outside the function. Actually it is nested function when I call the parent the outside function is redeclared. I want to avoid it.

If there is something in modern javascript from which we can get how many times it is called.

fn(){
}

fn()

Upvotes: 1

Views: 144

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074959

There's nothing built into JavaScript that tells you how many times a function has been called. If you want that information, you have to store it somewhere that persists beyond the duration of the function call — e.g., a variable outside the function, or similar.

A variable specifically for this purpose outside the function would be best practice if possible, but you've said you don't want one (or can't have one), so a very much less ideal approach would be to store the information on the function itself. Functions are objects, which means you can add properties to them:

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

Inside a function, its name is in scope as an identifier, referring to the function. So the code above gets the value of a callCount property from the function (defaulting it to 0 if it isn't there or has a falsy value), then sets the property to that value plus one.

That will only count the number of times that function was called. You said your function was nested. I couldn't tell from your question whether you wanted to know the total calls to the function, or the calls to that version of the function created by the call to the parent function. The above give you the latter. If you want the former, you could store the information on the parent function:

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

But again, I don't recommend it if you can avoid it. Use a dedicated variable if you can.

Live Examples:

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;
}

Using a variable (I realize you've said you don't want to or can't, but for others, and as an alternative...):

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;
}

Upvotes: 3

Related Questions