JavaScript 函数闭包值丢失
JavaScript function closure value lost
Closure 值在函数中得到 lost 作为 callback 传递给定义的另一个函数通过new Function()
方法。
代码
如何固定函数 baz()
访问 回调 中的闭包值?
注:函数foo()
不可修改
const foo = () => {
const b = 2;
return (a) => {
return a + b; // unable to access `b` here
};
};
const bar = (a = 1, callback = foo()) => callback(a);
const baz = new Function(["a = 1", `callback = ${foo()}`], "return callback(a)");
console.log(bar(1)); // works fine and prints 3
console.log(baz(1)); // throws Uncaught ReferenceError: b is not defined
我相信 Function 构造函数只在全局范围内执行,不会创建闭包。这个答案可能对你有帮助:
不要对函数使用字符串插值。可以在这里看到发生了什么:
const foo = () => {
const b = 2;
return (a) => a+b;
};
console.log(new Function(["a = 1", `callback = ${foo()}`], "return callback(a)"))
函数 (a) => a+b
被转换为字符串,然后将其放入新函数的源代码中。是的,这会丢失闭包 - 它会丢失整个函数对象。
相反,只写
const foo = () => {
const b = 2;
return (a) => a+b;
};
const bar = function(a = 1, callback = foo()) { return callback(a); };
const baz = new Function(["a = 1", "callback = foo()"], "return callback(a)");
console.log(bar(1));
console.log(baz(1));
console.log(bar);
console.log(baz);
正如您从记录的函数中看到的那样,它们的代码现在是等效的 - 由于演示片段中的所有内容都是全局的,因此它们的工作方式也相同。
当 foo
(或您希望从函数代码字符串访问的任何其他内容)定义在本地范围内时,情况会有所不同。在这种情况下,您需要使用 trick like this 来显式地使该值可用于动态生成的代码。
Closure 值在函数中得到 lost 作为 callback 传递给定义的另一个函数通过new Function()
方法。
代码
如何固定函数 baz()
访问 回调 中的闭包值?
注:函数foo()
不可修改
const foo = () => {
const b = 2;
return (a) => {
return a + b; // unable to access `b` here
};
};
const bar = (a = 1, callback = foo()) => callback(a);
const baz = new Function(["a = 1", `callback = ${foo()}`], "return callback(a)");
console.log(bar(1)); // works fine and prints 3
console.log(baz(1)); // throws Uncaught ReferenceError: b is not defined
我相信 Function 构造函数只在全局范围内执行,不会创建闭包。这个答案可能对你有帮助:
不要对函数使用字符串插值。可以在这里看到发生了什么:
const foo = () => {
const b = 2;
return (a) => a+b;
};
console.log(new Function(["a = 1", `callback = ${foo()}`], "return callback(a)"))
函数 (a) => a+b
被转换为字符串,然后将其放入新函数的源代码中。是的,这会丢失闭包 - 它会丢失整个函数对象。
相反,只写
const foo = () => {
const b = 2;
return (a) => a+b;
};
const bar = function(a = 1, callback = foo()) { return callback(a); };
const baz = new Function(["a = 1", "callback = foo()"], "return callback(a)");
console.log(bar(1));
console.log(baz(1));
console.log(bar);
console.log(baz);
正如您从记录的函数中看到的那样,它们的代码现在是等效的 - 由于演示片段中的所有内容都是全局的,因此它们的工作方式也相同。
当 foo
(或您希望从函数代码字符串访问的任何其他内容)定义在本地范围内时,情况会有所不同。在这种情况下,您需要使用 trick like this 来显式地使该值可用于动态生成的代码。