Tengo una función cuadrada, por ejemplo, en mi sistema como
function square(a) { console.log(a); return a * a; }Esta función cuadrada se llama muchas veces durante el ciclo de vida del programa como
square(5); square(1); square(2); square(3); Ahora el problema es que quiero obtener el conteo de las veces que se llama a la función cuadrada en un momento dado como cuadrado. el square.count debería devolver 4
La solución debe funcionar no solo con la función cuadrada, sino que también debe ser escalable y aplicable a otras funciones disponibles en el sistema. Por ejemplo, si también tengo una función de power(a,n) , entonces debería poder obtener el recuento de la función de potencia mediante algo como power.count
Puede crear una función que envuelva una función de destino y registre esa información, así:
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; }Luego reemplazas la función así:
square = addCounter(square);Ahora cada vez que lo llama, el contador se incrementa.
Ejemplo en vivo:
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; } Es posible que no se moleste con el bit de length , es inusual que el código mire la length de las funciones, pero está ahí para ser exhaustivo. (Debe usar defineProperty para establecer la length . Es una propiedad de solo lectura, pero es configurable, por lo que podemos redefinirla).
Solo para completar: si algo ha tomado su propia referencia a esa función antes de actualizarla, entonces las llamadas a través de esa otra referencia no se contarán. Pero eso es inusual, es de esperar que no tenga un código que lo haga. Un lugar en el que podría encontrarse es si está utilizando módulos CommonJS (ya sea directamente, o porque su paquete convierte la sintaxis del módulo estándar de JavaScript a CommonJS, como lo hacen algunos) y lo exporta antes de reemplazarlo (lo que parece bastante improbable) . La razón por la que sería un problema es que con los módulos CommonJS, lo que se exporta es una copia de la referencia de la función. No es un problema con los módulos de JavaScript estándar ( import / export ) que se usan de forma nativa, porque las importaciones son enlaces en vivo a la exportación original, por lo que lo anterior funcionaría bien con ella.