Los valores de cierre se pierden en una función que se pasa como devolución de llamada a otra función definida por el new Function() .
¿Cómo se puede arreglar la función baz() para acceder a los valores de cierre en la devolución de llamada?
Nota: La función foo() no se puede modificar.
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 definedNo utilice la interpolación de cadenas con una función. Lo que está pasando se puede ver aquí:
const foo = () => { const b = 2; return (a) => a+b; }; console.log(new Function(["a = 1", `callback = ${foo()}`], "return callback(a)")) La función (a) => a+b se convierte en una cadena, que luego se coloca en el código fuente de la nueva función. Sí, esto pierde el cierre, pierde todo el objeto de función.
En su lugar, simplemente escriba
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);Como puede ver en las funciones registradas, su código ahora es equivalente, y dado que todo en el fragmento de código de demostración es global, también funcionan de la misma manera.
Es un poco diferente cuando foo (o cualquier otra cosa a la que desee acceder desde la cadena de código de función) se define en un ámbito local. En ese caso, necesitará usar un truco como este para hacer que el valor esté explícitamente disponible para el código generado dinámicamente.
Creo que los constructores de funciones solo se ejecutan dentro del alcance global y no crean cierres. Esta respuesta puede ayudarte: