首页 > 解决方案 > 使用对象选择运行哪个函数(动态)

问题描述

从客户端(html)发送表单,服务器端通过选择选项之一决定运行哪个功能。

const decideWho = (form) => {
  const choice = form.choice;
  const obj = { key1 : 'func1(form.input1)',
key2 : 'func2(form.input2)'......};
return eval(obj[choice]||obj[default]);
}

由于其他一些问题,此代码被放置并且Josh Wulf提到了使用 eval 的危险。

所以我来了。我无法搜索与我的情况相关的内容,所以如果您知道任何已回答的问题,请告诉我。

我的问题是,起初我只是把 obj 的值不带引号。然后灾难发生了。当最后一行obj[choice]||obj[default]被调用时,obj 中的所有函数都被调用并且一些函数在重复迭代。我不知道出了什么问题。

不仅如此。

const someFunc = () => {
const a = {
      sourceFolder: "",
      aFolder: "1OoK3j",
      bFolder: "1M_cyv",
      cFolder: "11maBJ",
      dFolder: "1QxA8P",
      eFolder: "11lG"};
    for (let i in a) 
      eval(`var ${i} = getFolder(a['${i}']);`);

..move files to the destination above.
}


const getFolder = id => {
  try {
    if (id) {
      return DriveApp.getFolderById(id);
    } else return DriveApp.getRootFolder();
  } catch (e) {
  // If the folder by the id doesn't exists, return root folder.
    return DriveApp.getRootFolder();
  }
}

我不想使用相同的函数声明每个文件夹。所以我把它们放在 obj 中,没有 eval,迭代。

for (let i in a) var i = getFolder(a[i]);

这里又是灾难。当我调用 aFolder 期望它会返回具有提到的 id 的文件夹时,它会迭代对象中的所有文件夹。

因此,为了救援,值用引号和 eval 临时包裹起来。

这里应该做什么?

** 已编辑 ** 我正在尝试采用函数构造函数。

const aa = form => `id: ${form.id}`;
const bb = () => "I'm b";
const aaa = form => {
  const obj = {
    key1 : 'aa(form)',
    key2 : 'bb'
  };
  const handleIt = new Function('return ' + obj[form.choice])();
  console.log(handleIt());
}
const cc = () => {
  let form = {id: 'student 1', choice: 'key1'};
  aaa(form);
  form = {id: 'student 2', choice: 'key2'};
  aaa(form); 
}

这些被简化只是为了问一个问题,但真正的功能很长。 当我表演

form = {id: 'student 2', choice: 'key2'};
  aaa(form); 

它按预期工作。但是当一个参数应该被传递时,它说没有定义形式。

let form = {id: 'student 1', choice: 'key1'};
  aaa(form);

如果函数构造函数是解决方案,我需要在哪里以及如何添加参数?

const aaa = form => {
  const obj = {
    key1 : 'aa(form)',
    key2 : 'bb'
  };
  const handleIt = new Function('return ' + obj[form.choice])();
  console.log(handleIt());
}

编辑2我在没有评估的情况下完成了第一个。

const decideWho = myForm => {
  const obj = {
    key1 : func1(myForm),
    key2 : func2()
  };
  const handleIt = () => {return obj[myForm.choice];};
  console.log(handleIt());
}

标签: javascriptgoogle-apps-scripteval

解决方案


好吧,你不应该使用eval的事实并不意味着你不能使用new Function。事实上,这个问题对两者之间的差异进行了很好的讨论

所以..也许你应该把你的代码从

const decideWho = (form) => {
  const choice = form.choice;
  const obj = { 
     key1 : 'func1(form.input1)',
     key2 : 'func2(form.input2)'
  };
  return eval(obj[choice]||obj[default]);
}

类似于:

const decideWho = (form) => {
  const choice = form.choice;
  const obj = { 
     key1 : 'return true',
     key2 : 'return 7'
  };
  return new Function(obj[choice]||obj[default]);
}

然后只需调用您的处理程序:

 const funcHandler = decideWho(myForm)
 funcHandler()

如果你也想传递参数,请参考这个MDN示例


推荐阅读