Использование объекта для выбора, какую функцию запускать (динамически) - PullRequest
0 голосов
/ 24 февраля 2020

Со стороны клиента (html) отправляется форма, и сторона сервера решает, какую функцию запустить с помощью одной из опций выбора.

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

Из-за какого-то другого вопроса этот код был поставлен и Джо sh Вульф упомянул об опасности использования eval.

Так что я здесь. Я не смог выполнить поиск, связанный с моей ситуацией, поэтому, если вы знаете какой-либо ответ на вопрос, дайте мне знать.

Моя проблема в том, что сначала я просто поставил значение obj без кавычек. Затем произошла катастрофа. Когда вызывается последняя строка obj [выбор] || obj [по умолчанию] , вызываются все функции в объекте 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, ожидая, что он вернет папку с указанным идентификатором, он перебирает все папки в объекте.

Поэтому для спасения значения обертываются кавычкой и временно вычисляются.

Что здесь должно быть сделано?

** Отредактировано ** Я пытаюсь принять конструктор функции.

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 Первый получен без eval.

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

Ответы [ 2 ]

1 голос
/ 24 февраля 2020

Ну, тот факт, что вы не должны использовать 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 образец

0 голосов
/ 25 февраля 2020

Благодаря 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();
}

И второе тоже похоже, но на этот раз Переменная присваивания также является Dynami c. Это также решается с помощью комментария от { ссылка }

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

->

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

Если в «этом» нет зла, Я буду использовать таким образом. (Это функция на стороне сервера, поэтому я не могу использовать окно)

...