使用对象选择要动态运行的功能

问题描述 投票:0回答:2

从客户端(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的文件夹时,它将迭代对象中的所有文件夹。

因此,为了进行救援,将值用引号引起来并在时间上进行评估。

应该在这里做什么?

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

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());
}
javascript google-apps-script eval
2个回答
1
投票

[嗯,他事实上您不应该使用eval并不意味着您不能使用new Function。实际上,question很好地讨论了两者之间的区别

所以..也许您应该从以下位置转换代码

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示例


0
投票

由于stackoverflow和人们的贡献,我得以轻松解决我的问题。我的两个问题都是动态调用函数,而第一个更容易使用@ymz的建议。

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 = myForm => {
  const obj = {
    key1 : ()=> func1(myForm),
    key2 : ()=> func2()
  };
  const handleIt = () => obj[`${myForm.choice}`]();
  return handleIt();
}

并且第二个也类似,但是这次分配变量也是动态的。这也得到了来自https://stackoverflow.com/a/28063322/12775761

for (let i in a) 
  eval(`var ${i} = getFolder(a['${i}']);`);

->

for (let i in a) this[`${i}`] = getFolder(a[i]);

如果“ this”中没有邪恶,我将以此方式使用。(这是服务器端功能,因此我无法使用窗口)

© www.soinside.com 2019 - 2024. All rights reserved.