Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

somehow I need to update all the functions so that I can get how many times each function is called during the program lifecycle

I have a square function for example in my system like

function square(a) {
  console.log(a);
  return a * a;
}

This square function is called many times during the lifecycle of the program like

square(5);
square(1);
square(2);
square(3);

Now the problem is that I want to get the count of the times square function is called at any given time like square.count should return 4

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

The solution should work not only with the square function but should also be scalable and be applicable to other functions available in the system. For e.g, if I have a power(a,n) function as well then I should be able to get the count for power function by something like power.count

>Solution :

You can create a function that wraps a target function and records that information, like this:

function addCounter(fn) {
    // Create a wrapper function
    const newfn = function(...args) {
        // In the wrapper, increment the count
        ++newfn.count;
        // Call original and return its return value
        return fn.apply(this, args);
    };
    // Set up the count
    newfn.count = 0;
    // Ensure the new function's `length` matches the original
    // (in case you have anything relying on it)
    Object.defineProperty(newfn, "length", {
        value: fn.length,
        configurable: true,
    });
    // Return the new function
    return newfn;
}

Then you replace the function like this:

square = addCounter(square);

Now whenever you call it, the counter gets incremented.

Live Example:

function addCounter(fn) {
    // Create a wrapper function
    const newfn = function(...args) {
        // In the wrapper, increment the count
        ++newfn.count;
        // Call original and return its return value
        return fn.apply(this, args);
    };
    // Set up the count
    newfn.count = 0;
    // Ensure the new function's `length` matches the original
    // (in case you have anything relying on it)
    Object.defineProperty(newfn, "length", {
        value: fn.length,
        configurable: true,
    });
    // Return the new function
    return newfn;
}

function square(a) {
    console.log(a);
    return a * a;
}

square = addCounter(square);
console.log(square(5));
console.log(`square.count = ${square.count}`);
console.log(square(1));
console.log(`square.count = ${square.count}`);
console.log(square(2));
console.log(`square.count = ${square.count}`);
console.log(square(3));
console.log(`square.count = ${square.count}`);
.as-console-wrapper {
    max-height: 100% !important;
}

You might not bother with the length bit, it’s unusual for code to look at the length on functions, but it’s there to be thorough. (You have to use defineProperty to set length. It’s a read-only property, but it’s configurable, so we can redefine it.)

Just for completeness: If anything has grabbed its own reference to that function before you update it, then calls through that other reference won’t be counted. But that’s unusual, hopefully you don’t happen to have code doing it. One place you could run into that is if you’re using CommonJS modules (either directly, or because your bundler converts JavaScript standard module syntax to CommonJS instead, as some do) and you export it before you replace it (which seems fairly unlikely). The reason that would be a problem is that with CommonJS modules, what’s exported is a copy of the function reference. It’s not a problem with standard JavaScript modules (import/export) used natively, because imports are live bindings to the original export, so the above would work just fine with it.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading