动态构建功能

时间:2019-07-30 12:32:43

标签: javascript ecmascript-6

是否可以基于其他函数参数动态构建函数?

例如:

基本功能:

const someFunction = (functionName, functionParams) => {
  // Function Built here
};

someFunction("colorFunction", ["red", true]);

我希望它构建类似于以下内容的东西: 我需要将Array解构为单独的参数,但是我不确定这有多简单?而且我不知道如何使用第一个String来调用函数名称?

functionName(...functionParams);

在我脑海中这样的工作:

const colorFunction = (color, bool) => {
  console.log("Colour: " + color);
  console.log("Bool: " + bool);
};

对此有点困惑-我觉得我离一百万英里远,但是我不确定!任何帮助都会很棒,谢谢!!!

编辑-为什么?

我有一个带有click事件的react组件,该事件触发了redux动作。理想情况下,此操作将向我的减速器投放一些东西,并异步调用此“动态”函数。我可以用大量的if / elses来做到这一点,但是我认为,如果可以通过这种方式构建函数,那不是一种很干净的方法。

2 个答案:

答案 0 :(得分:2)

首先,您需要确定要动态调用的函数的存储位置。如果它们是全局函数,则可以使用window来调用它们:

const someFunction = (functionName, functionParams) => {
    window[functionName]();
};

如果它们是对象的方法,则可以使用该对象执行类似的操作:

const someFunction = (functionName, functionParams) => {
    myObject[functionName]();
};

关于如何传递参数,这里有两个选择。如果您正在运行最新版本的JS或使用polyfills,则可以使用散布运算符:

const someFunction = (functionName, functionParams) => {
    window[functionName](...functionParams);
};

否则,您始终可以依靠apply方法:

const someFunction = (functionName, functionParams) => {
    window[functionName].apply(null, functionParams);
};

apply方法中的第一个参数是您希望传递给函数的上下文,在您的情况下,似乎不需要,因此为null值。

编辑:Bergi提到用bind更正了apply

答案 1 :(得分:0)

您要寻找的是Function#bind,以便制作thunk-本质上是一个不带参数的函数,该函数用于延迟计算。

使用.bind可以对函数执行partial application。对于您的情况,您只需应用所有参数,并只在最后保留执行步骤:

//your function
const colorFunction = (color, bool) => {
  console.log("Colour: " + color);
  console.log("Bool: " + bool);
};

//partially apply all argument to it

const thunk = colorFunction.bind(null, "red", true);

//this can now be passed around and executed at a later point
setTimeout(thunk, 3000);

console.log("wait 3 seconds");

由于函数在JavaScript中是first class members,因此您可以通过这种方式传递任何函数。如果您确实需要一个可以将他人变成笨拙的函数,那么您可以轻松地做到这一点:

const toThunk = (func, args) => func.bind(null, ...args);

您的someFunction是哪个,但只是为了更清楚地重命名了名称和参数。

相关问题