在javascript中,如何通过"new Function()"创建函数时设置函数参数名称?

In javascript, how to set function parameter names when creating function via "new Function()"?

尝试通过 new Function(fnBody) 设置函数中的参数名称,以关联到动态函数体文本变量。

const myFnBody = " return myParam; ";  // dynamic fn-text, expecting 'myParam' variable.
const myFunc = new Function(myFnBody);  // create the function with the body-text.
const myParamVal = "Hello world.";  // setup argument
console.log(myFunc(myParamVal));   // output: undefined, not 'Hello world.' as desired.

控制台输出是 undefined 因为“myParam”没有链接到函数调用上下文中的第一个参数 (arguments[0])。

想要将第一个 arg (arguments[0]) 分配给“myParam”参数的函数,如:

const myFunc = function (myParam) { return myParam; }

我需要这个来编写 运行 考虑参数名称的动态代码:类似于 CommonJS 的“require”和“exports”。该代码期望使用特定的 parameter/variable 名称传递值。

我能想到的最好办法是通过 arguments 集合预先设置一个变量,然后添加实际的动态函数文本:

let dynamicFnText = {SOME USER DEFINED FN BODY-TEXT, such as "return myParam;"};
let myFnBody = "";  // start the fn-body as text (string)
myFnBody += "const myParam = arguments[0];";  // prefix a parameter value via the arguments
myFnBody += dynamicFnText;  // append the dynamic fn text, which expects 'myParam' variable.

let myFunc = new Function(myFnBody);
let myParam = "Hello world.";
console.log(myFunc(myParam));  // 'Hello world."

使用 eval:是的,我可以使用 eval(),如:

let myFunc = eval("(function (myParam) {" + dynamicFnText + "})");  // fn with 'myParam'

但是,我试图避免“邪恶的”eval() 功能。我不应该担心以这种方式使用 eval() 吗?

我想我期待函数 (new Function()) 实例上的某种 .setParameters() 方法。或者类似 new Function(paramNamesArray, fnBody).

感谢任何帮助。谢谢。

Or something like new Function(paramNamesArray, fnBody)

关闭!它将是 new Function(...paramNamesArray, fnBody).

Function constructor 支持多个参数。 last 参数是函数体。之前的任何参数都是参数的名称。

所以在你使用 myParam 的情况下,你将传递 "myParam: 作为第一个参数:

const myFunc = new Function("myParam", myFnBody);

实例:

const myFnBody = " return myParam; ";
const myFunc = new Function("myParam", myFnBody);
const myParamVal = "Hello world.";
console.log(myFunc(myParamVal));

回到您的 paramNamesArray 概念,您可能会:

const myFunc = new Function(...paramNamesArray, myFnBody);

实例:

const myFnBody = " return myParam; ";
const paramNamesArray = ["myParam"];
const myFunc = new Function(...paramNamesArray, myFnBody);
const myParamVal = "Hello world.";
console.log(myFunc(myParamVal));


However, i'm trying to avoid the "evil" eval() function. Should i not be concerned about using eval() in this manner?

new Function 只是 最小的 问题比使用 eval 少一点。两者都允许任意代码执行,这意味着两者都要求您完全信任您正在评估的代码。您不希望从用户 A 获取代码并在用户 B 的上下文中获取 运行 该代码(除非用户 B 明确期望并允许这样做,就像我们在此处单击“运行 代码片段”时一样) . 非常 new Functioneval 问题稍微少一些的次要方式是它不能用于访问本地范围内的事物,并且 eval 能够。 (您可以通过使用 indirect eval 来解决这个问题,它也不能使用局部作用域。)

有时候 evalnew Function 是您需要使用的,但这些用例是 非常 罕见。底线:如果您担心使用 eval,请担心使用 new Function(几乎) 就像“坏”一样。

调用时除了指定函数体外,只需指定参数名即可 new Function:

const myFnBody = " return myParam; ";  // dynamic fn-text, expecting 'myParam' variable.
const myFunc = new Function('myParam', myFnBody);  // create the function with the body-text.
const myParamVal = "Hello world.";  // setup argument
console.log(myFunc(myParamVal));

由于这来自用户,请确保用户提供他们的函数将接受的参数列表,然后根据需要将它们列在 new Function 参数列表中。

Should i not be concerned about using eval() in this manner?

不,你不应该 - new Functioneval 一样不安全。如果您将使用 new Function,您也可以使用 eval(从安全的角度来看),因为它允许执行动态(并且可能不安全)代码。