我有一个函数返回函数。内部函数在其主体中使用父函数的参数。然后,我列出了通过使用不同参数调用父函数而生成的函数列表。这是一个例子:
function f(a) { return function(b) { return a * a + b; }; }
var fList = [f(-2), f(-1), f(0), f(1), f(2)];
这些来自图书馆,我无法修改它们。
我想知道是否有可能根据
fList
的参数值对 f
应用过滤器。例如,我可以获取 fList
中的项目,其中使用非负值调用 f
函数吗?我尝试在调试控制台中检查fList[0]
,但不幸的是无法取得任何进展。
我觉得这是不可能的。但是,由于当我调用
fList[0](2)
时,它使用 a
变量的 -2
值,我希望如此。
请不要建议使用反函数,这就是为什么我让它返回搜索参数加上内部参数的平方。上面是一个过于简单的例子,实际情况下的身体有很大不同,并且有一些副作用。
如果您的 fList 按数字顺序排列(如上所示),那么您就知道 fList 之前 0 的结果(即 f(0) = 0 * 0 + 0 = 0)中的每个元素都来自 a负数
如果您可以覆盖
f
:
function f(a) { return function(b) { return a * a + b; }; }
const param = Symbol();
// override f() and assign the param to it
f = a => {
const out = b => a * a + b;
out[param] = a;
return out;
};
var fList = [f(-2), f(-1), f(0), f(1), f(2)];
const positive = fList.filter(f => f[param] >= 0);
console.log(positive.map(f=>f(3)));
由于原始库函数的实现未知,因此无法直接重写/重新实现和增强。
OP 的任务是捕获函数
a
的 f
参数值,既不知道 f
的实现,也不实际接触 f
本身。
这种场景只能通过基于函数包装方法的函数或方法修改来解决。
通过下一个提供的解决方案,OP 可以选择将临时创建的原始函数的修改版本重新分配给该函数的变量名(或命名空间),或者将其分配给另一个常量/变量。无论哪种方式,修改后的函数将始终具有原始函数的名称,因为该名称对于某些用例可能很重要。此外,为了更加通用,包装器不仅仅将传递的参数分配给返回的函数,而是将所有传递的参数分配为数组......
// - original library function of unknown
// implementation which therefore can not
// be directly rewritten and enhanced.
function f(a) {
return function (b) {
return a * a + b;
};
}
// - the task is to capture the `a` parameter value of function `f`.
// - thus, one has to rely on method-modification,
// based on a function wrapping approach.
// - ad hoc creation and re/assignment of the function's modified version.
f = (function (proceed) {
return ({
// preserve the original function's name.
[proceed.name]: function (...args) {
const result = proceed(...args);
if (typeof result === 'function') {
// - assign the entire `arguments` as array to the
// to be returned function's `args` property.
Reflect
.defineProperty(result, 'args', { value: args });
}
return result;
}
})[proceed.name];
}(f)); // provide the original function of unknown implementation.
const fList = [f(-2), f(-1), f(0), f(1), f(2)];
const nonNegativeParameterFList = fList.filter(f => f.args.at(0) >= 0);
console.log(
nonNegativeParameterFList.map(f => f(3))
);
console.log(
nonNegativeParameterFList.map(f => f.args)
);
console.log('f.name ...', f.name);
.as-console-wrapper { min-height: 100%!important; top: 0; }