Рекурсивная функция JavaScript выдает ошибку при вызове более одного раза с одним и тем же параметром

#javascript #arrays #object #eval

Вопрос:

Я совершенно новичок в JavaScript. Я создал рекурсивную функцию для генерации простых фраз на основе шаблонов для определенного набора данных. Пример этого изложен ниже. Функция случайным образом выбирает объект, соответствующий категории ctgNo . Он перебирает объект, чтобы получить его компоненты, а затем присваивает им связанные переменные, содержащие списки массивов.

Это и есть объект:

 const ctg_ptr = {
  1: [
    { S: [["mA_2", "vrb_better", "pro_your", "N_1"]] },
  ],
  2: [
    { S: [["mA", "vrb_give", "H", "adj", "N", "prep"]] },
    { S: [["mA", "vrb2_2", "H", "adj", "N", "prep"]] },
  ],
  3: [
    { S: [["mA_2", "vrb_better", "pro_your", "N_1"]] },
  ],
};
 

Компоненты объекта , такие как mA_2 и т.д., vrb_better Определяются следующим образом:

 const vrb_better = [["running"], ["jumping"]];
const mA_2 = [["This morning"], ["That afternoon"]];
const pro_your = [["with your dog"]];
const N_1 = [["in the park"], ["in the street"]];
 

и т.д.

Выше приведен набор данных, который я использую для выполнения следующей функции:

 function partPhrase(ctgNo) {
  let start = "S";
  let expansion = [];
  let rules = {};
  debugger;
  let rndObjVal =
    ctg_ptr[ctgNo][
      Math.floor(
        Math.random() * (Object.values(ctg_ptr[ctgNo]).length - 1 - 0   1)   0
      )
    ];

//this is the loop where the error happens

  for (let key in rndObjVal) {
    split = rndObjVal[key];
    for (let i in split) {
      for (let j in split[i]) {
        ary = split[i][j];
        rndObjVal[ary] = eval(ary);
      }
    }
  }

  rules = rndObjVal;

  console.log(rules);

  let result = expand(start, expansion);

  function expand(start, expansion) {
    if (rules[start]) {
      let pick = rules[start][Math.floor(Math.random() * rules[start].length)];
      for (let i = 0; i < pick.length; i  ) {
        expand(pick[i], expansion);
      }
    } else {
      expansion.push(start);
    }
    return expansion.join(" ");
  }
  return resu<
}

let phr_1 = partPhrase(1);
let phr_2 = partPhrase(1);
 

Функция работает нормально при первом вызове. Проблема возникает при многократном вызове его с использованием одного и того же параметра, такого как «1» в приведенном выше примере. В этом случае цикл for-in не завершится (как в первом случае), а начнет входить во вложенный объект, указывая, что объект rndObjVal содержит данные из предыдущего вызова функции. Как это можно исправить, чтобы каждый раз, когда функция вызывается с теми же параметрами, она выполнялась так же гладко, как и в первый раз?

Примечание: Я не получаю ошибку, если дважды запускаю функцию с параметрами «1» и «3», где свойства объектов идентичны.

Во-вторых, есть ли способ улучшить код лучше, так как я не слышал много хорошего об eval().

Комментарии:

1. Когда вы устанавливаете rndObjVal , вы не делаете копию части объекта; это ссылка.