我需要以某种方式更新所有函数,以便我可以获得在程序生命周期中调用每个函数的次数
somehow I need to update all the functions so that I can get how many times each function is called during the program lifecycle
我的系统中有一个平方函数,例如
function square(a) {
console.log(a);
return a * a;
}
这个square函数在程序的生命周期中被调用了很多次
square(5);
square(1);
square(2);
square(3);
现在的问题是我想获得在任何给定时间调用时代平方函数的计数,例如 square.count
应该 return 4
该解决方案不仅应适用于平方函数,而且还应具有可扩展性并适用于系统中可用的其他函数。例如,如果我也有一个 power(a,n)
函数,那么我应该能够通过 power.count
之类的东西获得幂函数的计数
您可以创建一个包装目标函数并记录该信息的函数,如下所示:
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;
}
然后你像这样替换函数:
square = addCounter(square);
现在无论何时调用它,计数器都会递增。
实例:
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;
}
您可能不会为 length
位而烦恼,代码在函数上查看 length
是不寻常的,但它在那里是彻底的。 (你必须使用defineProperty
设置length
。它是一个read-only属性,但它是可配置的,所以我们可以重新定义它。)
只是为了完整性:如果在您更新之前任何东西已经获取了对该函数的引用,那么通过其他引用的调用将不会被计算在内。但这是不寻常的,希望你不会碰巧有代码来做这件事。你可以 运行 进入其中的一个地方是,如果你正在使用 CommonJS 模块(直接使用,或者因为你的捆绑器将 JavaScript 标准模块语法转换为 CommonJS,就像某些人所做的那样)并且你在你之前导出它替换它(这似乎不太可能)。出现问题的原因是对于 CommonJS 模块,导出的是函数引用的副本。 不是本地使用的标准JavaScript模块(import
/export
)的问题,因为导入是原始导出的实时绑定,所以以上就可以正常工作了。
我的系统中有一个平方函数,例如
function square(a) {
console.log(a);
return a * a;
}
这个square函数在程序的生命周期中被调用了很多次
square(5);
square(1);
square(2);
square(3);
现在的问题是我想获得在任何给定时间调用时代平方函数的计数,例如 square.count
应该 return 4
该解决方案不仅应适用于平方函数,而且还应具有可扩展性并适用于系统中可用的其他函数。例如,如果我也有一个 power(a,n)
函数,那么我应该能够通过 power.count
您可以创建一个包装目标函数并记录该信息的函数,如下所示:
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;
}
然后你像这样替换函数:
square = addCounter(square);
现在无论何时调用它,计数器都会递增。
实例:
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;
}
您可能不会为 length
位而烦恼,代码在函数上查看 length
是不寻常的,但它在那里是彻底的。 (你必须使用defineProperty
设置length
。它是一个read-only属性,但它是可配置的,所以我们可以重新定义它。)
只是为了完整性:如果在您更新之前任何东西已经获取了对该函数的引用,那么通过其他引用的调用将不会被计算在内。但这是不寻常的,希望你不会碰巧有代码来做这件事。你可以 运行 进入其中的一个地方是,如果你正在使用 CommonJS 模块(直接使用,或者因为你的捆绑器将 JavaScript 标准模块语法转换为 CommonJS,就像某些人所做的那样)并且你在你之前导出它替换它(这似乎不太可能)。出现问题的原因是对于 CommonJS 模块,导出的是函数引用的副本。 不是本地使用的标准JavaScript模块(import
/export
)的问题,因为导入是原始导出的实时绑定,所以以上就可以正常工作了。