【问题标题】:JavaScript function closure value lostJavaScript 函数闭包值丢失
【发布时间】:2022-01-05 20:19:36
【问题描述】:

闭包值在作为回调传递给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

【问题讨论】:

    标签: javascript function callback closures uncaught-reference-error


    【解决方案1】:

    不要在函数中使用字符串插值。在这里可以看到正在发生的事情:

    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);

    从记录的函数中可以看出,它们的代码现在是等效的 - 由于演示 sn-p 中的所有内容都是全局的,因此它们的工作方式也相同。

    foo(或您想从函数代码字符串访问的任何其他内容)在本地范围内定义时,情况会有所不同。在这种情况下,您需要使用 trick like this 明确地使动态生成的代码可以使用该值。

    【讨论】:

    • 好吧,它似乎在这里工作,但在我的开发环境中却不行。代码无法编译并抛出 ReferenceError: foo is not defined at eval
    • 那么,您的开发环境是什么? foo 是全局变量吗?为什么说eval,代码没有用到?
    • 我的开发环境是一个编码测试平台。不,foo 不是那里的全局变量,因为该文件除了您的解决方案之外什么都没有。它说eval 可能是因为编译器与此语法不兼容,或者它正在尝试评估我的代码。好吧,该平台还针对某些测试用例运行了一些 Mocha 测试,但它们似乎没有抛出错误,因为它们甚至没有运行,因为代码在编译时错误时失败。如果您认为您的解决方案无法解决此错误,我仍然可以接受您的回答,因为它在正常的开发环境下似乎可以正常工作。
    • 如果它不是全局的,构造的Function 看不到它 - 试试我链接的方法,const baz = new Function("{foo}", "return function(a = 1, callback = foo()) { return callback(a); };")({foo})。但是ReferenceError 听起来不像是编译时错误,如果您需要有关该平台的进一步帮助,请提出一个新问题。
    【解决方案2】:

    我相信 Function 构造函数只在全局范围内执行并且不会创建闭包。这个答案可能对您有所帮助:

    Function Constructor MDN

    【讨论】:

      猜你喜欢
      • 2010-12-22
      • 2013-03-18
      • 1970-01-01
      • 2015-11-07
      • 1970-01-01
      • 1970-01-01
      • 2016-06-24
      • 1970-01-01
      • 2022-07-06
      相关资源
      最近更新 更多