是否可以使用接收数据作为参数的函数的闭包范围?
Posted
技术标签:
【中文标题】是否可以使用接收数据作为参数的函数的闭包范围?【英文标题】:Is it possible to use closure scope of a function that receives data as a argument? 【发布时间】:2022-01-08 07:45:30 【问题描述】:有一个函数需要一个接收数据参数的回调函数。我需要一种在回调中访问 foo 的方法。从阅读中我发现闭包范围可以成为解决方案,但是我很难找到一个回调也接收数据对象(或任何变量)的示例。
const foo = 1;
this.editor.functionThatExpectsCallback('genericString', (data) =>
// do stuff with foo here, e.g.
const bar = foo + data.num;
return bar;
)
基本上问题是 foo 在回调范围内未定义,我需要定义它,同时仍保持对数据的访问。我非常感谢我能在这里得到的任何帮助。如果您需要更多信息,我很乐意提供。
【问题讨论】:
"基本上问题是 foo 在回调范围内未定义" 那么您的代码不会证明这一点,因为它将用你有代码。 好吧,为了这篇文章,我简化了我的代码,但我没有访问权限。你确定总是这样吗? Yes, I am 我相信回调函数是在不同的服务中远程执行的。这可能是 foo 未定义的原因吗? 首先,您可能必须检查所调用内容的文档——它可能会为此提供一种机制。如果没有,那么很遗憾,您将不得不从new Function("data", `const bar = $foo + data.num; return bar;`)
之类的字符串生成函数,但您必须非常小心,不要碰巧产生无效代码。
【参考方案1】:
您当前的代码是正确的,因为that is how scopes work - 任何来自外部范围的内容都可以在内部范围内看到。
它不起作用的唯一原因是函数被序列化然后反序列化 - 这完全删除了所有范围信息:
//different scope here
const foo = 1;
const result = functionThatExpectsCallback('genericString', (data) =>
// do stuff with foo here, e.g.
console.log("foo is:", typeof foo);
const bar = foo + data.num;
return bar;
);
console.log(result);
//dummy implementation that serialises and deserialises a function to run it:
function functionThatExpectsCallback(arg, callback)
return runFromString(callback.toString());
function runFromString(strFunc)
const fn = eval(`($strFunc)`);
return fn( num: 2 );
解决这个问题的第一种方法是检查使用的任何库的文档 - 它可能提供一种发送额外参数的方法。
如果这不是一个选项,那么您需要以肮脏的方式进行操作并从字符串生成函数。你可以使用the Function
constructor 来做到这一点
//different scope here
const foo = 1;
const generatedFunction = new Function("data", `
// do stuff with foo here, e.g.
const bar = $foo + data.num;
return bar;
`);
const result = functionThatExpectsCallback('genericString', generatedFunction);
console.log(result);
function functionThatExpectsCallback(arg, callback)
return runFromString(callback.toString());
function runFromString(strFunc)
const fn = eval(`($strFunc)`);
return fn( num: 41 );
您必须非常小心,因为从字符串生成函数时很容易引入小错误,并且最终可能会出现无效代码。例如,如果foo
是字符串foo = "hello"
,则生成的代码将是const bar = hello + data.num;
,这是无效的,因为hello
将是一个从未定义的变量,而不是字符串文字"hello"
。
【讨论】:
以上是关于是否可以使用接收数据作为参数的函数的闭包范围?的主要内容,如果未能解决你的问题,请参考以下文章
Python基础:19.函数式编程:高阶函数返回函数闭包偏函数
Groovy闭包 Closure ( 闭包作为函数参数 | 代码示例 )
Groovy闭包 Closure ( 闭包作为函数参数 | 代码示例 )
带有不匹配参数的闭包调用:函数'_RegisterState.build.<匿名闭包>'接收者:闭包:(字符串)=> Null