如何在 JavaScript 中重做 for...of 循环?

How do I redo a for...of loop in JavaScript?

在Ruby中,redo关键字可用于返回到循环的开头而不消耗输入。我想对 JavaScript.

中的 for...of 循环做同样的事情
const scan = lexer => function* (string) {
  let [token, table] = lexer;

  for (const character of string) {
    const next = table.get(character);

    if (next) {
      [token, table] = next.value;
    } else if (token) {
      yield token.value;
      [token, table] = lexer;
      // redo the current iteration without consuming input
    } else {
      throw new SyntaxError("Unexpected character", character);
    }
  }

  if (token) yield token.value;
  else throw new SyntaxError("Unexpected end of input");
}

通常情况下,您只需不增加常规 for 循环的索引即可。但是,我必须使用 for...of 循环,因为它会遍历字符串的 Unicode 代码点,而常规 for 循环会遍历字符串的 UTF-16 代码单元。

如何在不重复代码的情况下返回到循环的开头?

只需使用一个内循环:

 for (const character of string) {
   while(true) {
     const next = table.get(character);       
     if (next) {
       [token, table] = next.value;
       break;
     } else if (token) {
       yield token.value;
       [token, table] = lexer;      
       // don't break, redo
     } else {
       throw new SyntaxError("Unexpected character", character);
       break;
    }
  }
}

重启整个循环:

在你的例子中其实很简单:

 yield* scan(lexer)(string);
 return;

如果您不想重新启动整个功能,请添加一个 IIFE 并记住:

 yield* (function redo*() {
   //...
  yield* redo();
  return;
})();

如果你真的需要跳转,使用标签(请不要):

 restart: while(true) {
  // do stuff
  continue restart;
  //...
  break;
}