是否可以使用接收数据作为参数的函数的闭包范围?
Is it possible to use closure scope of a function that receives data as a argument?
有一个函数需要一个接收数据参数的回调函数。我需要一种在回调中访问 foo 的方法。通过阅读,我发现闭包范围可以是解决方案,但是我一直在努力寻找一个示例,其中回调也接收数据对象(或与此相关的任何变量)。
const foo = 1;
this.editor.functionThatExpectsCallback('genericString', (data) => {
// do stuff with foo here, e.g.
const bar = foo + data.num;
return bar;
})
基本上问题是 foo 在回调范围内未定义,我需要定义它,同时仍然保持对数据的访问。我真的很感激我能在这里得到的任何帮助。如果您需要更多信息,我很乐意提供。
您当前的代码 是正确的 因为 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"
.
有一个函数需要一个接收数据参数的回调函数。我需要一种在回调中访问 foo 的方法。通过阅读,我发现闭包范围可以是解决方案,但是我一直在努力寻找一个示例,其中回调也接收数据对象(或与此相关的任何变量)。
const foo = 1;
this.editor.functionThatExpectsCallback('genericString', (data) => {
// do stuff with foo here, e.g.
const bar = foo + data.num;
return bar;
})
基本上问题是 foo 在回调范围内未定义,我需要定义它,同时仍然保持对数据的访问。我真的很感激我能在这里得到的任何帮助。如果您需要更多信息,我很乐意提供。
您当前的代码 是正确的 因为 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"
.