Pet*_*son 122 javascript goto
我有一些我绝对必须使用的代码goto.例如,我想写一个这样的程序:
start:
alert("RINSE");
alert("LATHER");
repeat: goto start
Run Code Online (Sandbox Code Playgroud)
有没有办法在Javascript中这样做?
Pet*_*son 149
绝对!有一个名为Summer of Goto的项目允许您充分利用JavaScript,并将彻底改变您编写代码的方式.
此JavaScript预处理工具允许您创建标签,然后使用以下语法转到它:
[lbl] <label-name>
goto <label-name>
Run Code Online (Sandbox Code Playgroud)
例如,问题中的示例可以写成如下:
[lbl] start:
alert("LATHER");
alert("RINSE");
[lbl] repeat: goto start;
Run Code Online (Sandbox Code Playgroud)
请注意,您不仅限于简单的简单程序,如无休止的LATHER RINSE重复循环 - 提供的可能性goto是无穷无尽的,您甚至可以Hello, world!向JavaScript控制台发送消息538次,如下所示:
var i = 0;
[lbl] start:
console.log("Hello, world!");
i++;
if(i < 538) goto start;
Run Code Online (Sandbox Code Playgroud)
您可以阅读有关如何实现goto的更多信息,但基本上,它会执行一些JavaScript预处理,利用您可以使用带标签的while循环模拟goto这一事实.所以,当你写下"Hello,world!" 上面的程序,它被翻译成这样的东西:
var i = 0;
start: while(true) {
console.log("Hello, world!");
i++;
if(i < 538) continue start;
break;
}
Run Code Online (Sandbox Code Playgroud)
此预处理过程存在一些限制,因为while循环不能跨多个函数或块进行扩展.但这并不是什么大问题 - 我确信能够利用gotoJavaScript的好处绝对会让你感到压力.
以上链接导致goto.js库是ALL DEAD,这里是需要的链接:
goto.js(未压缩) --- parseScripts.js(未压缩)
来自Goto.js:
PS对于任何想知道的人(到目前为止总共为零人),Goto是一个由Paul Irish推广的术语,同时讨论这个脚本和PHP决定将goto添加到他们的语言中.
对于那些没有立即认识到这一切都是个玩笑的人,请原谅我.< - (保险).
pim*_*vdb 111
ECMAScript没有goto语句.
小智 32
实际上,我看到ECMAScript(JavaScript)DOES INDEED有一个goto语句.但是,JavaScript goto有两种风格!
goto的两种JavaScript风格称为标记为continue并标记为break.JavaScript中没有关键字"goto".goto是使用break和continue关键字在JavaScript中完成的.
在w3schools网站http://www.w3schools.com/js/js_switch.asp上或多或少地明确说明了这一点.
我发现标记为"继续"和"标记符"的文档有点笨拙地表达.
标记的中断和标记中断之间的差异是它们可以使用的位置.标记的continue只能在while循环中使用.有关更多信息,请参阅w3schools.
===========
另一种方法是使用一个巨大的while语句,里面有一个巨大的switch语句:
while (true)
{
switch (goto_variable)
{
case 1:
// some code
goto_variable = 2
break;
case 2:
goto_variable = 5 // case in etc. below
break;
case 3:
goto_variable = 1
break;
etc. ...
}
}
Run Code Online (Sandbox Code Playgroud)
小智 30
在经典JavaScript中,您需要使用do-while循环来实现此类代码.我认为你可能正在为其他东西生成代码.
这样做的方法,比如将字节码后发到JavaScript,就是将每个标签目标包装在"标记"的do-while中.
LABEL1: do {
x = x + 2;
...
// JUMP TO THE END OF THE DO-WHILE - A FORWARDS GOTO
if (x < 100) break LABEL1;
// JUMP TO THE START OF THE DO WHILE - A BACKWARDS GOTO...
if (x < 100) continue LABEL1;
} while(0);
Run Code Online (Sandbox Code Playgroud)
您使用的每个标记的do-while循环实际上为一个标签创建了两个标签点.一个在顶部,一个在循环结束.跳回使用继续和跳跃使用休息.
// NORMAL CODE
MYLOOP:
DoStuff();
x = x + 1;
if (x > 100) goto DONE_LOOP;
GOTO MYLOOP;
// JAVASCRIPT STYLE
MYLOOP: do {
DoStuff();
x = x + 1;
if (x > 100) break MYLOOP;
continue MYLOOP;// Not necessary since you can just put do {} while (1) but it illustrates
} while (0)
Run Code Online (Sandbox Code Playgroud)
不幸的是,没有其他办法可以做到这一点.
正常示例代码:
while (x < 10 && Ok) {
z = 0;
while (z < 10) {
if (!DoStuff()) {
Ok = FALSE;
break;
}
z++;
}
x++;
}
Run Code Online (Sandbox Code Playgroud)
所以说代码被编码为字节码所以现在你必须将字节码放入JavaScript中以模拟你的后端用于某种目的.
JavaScript风格:
LOOP1: do {
if (x >= 10) break LOOP1;
if (!Ok) break LOOP1;
z = 0;
LOOP2: do {
if (z >= 10) break LOOP2;
if (!DoStuff()) {
Ok = FALSE;
break LOOP2;
}
z++;
} while (1);// Note While (1) I can just skip saying continue LOOP2!
x++;
continue LOOP1;// Again can skip this line and just say do {} while (1)
} while(0)
Run Code Online (Sandbox Code Playgroud)
因此,使用这种技术可以很好地完成工作.除此之外,你可以做的事情不多.
对于普通的Javacript,你不需要使用goto,所以你应该在这里避免使用这种技术,除非你特意翻译其他样式代码以在JavaScript上运行.我认为这就是他们如何在JavaScript中启动Linux内核的例子.
注意!这都是天真的解释.对于正确的Js字节码后端,还要考虑在输出代码之前检查循环.可以检测到许多简单的while循环,然后您可以使用循环而不是goto.
Hen*_*est 14
const
start = 0,
more = 1,
pass = 2,
loop = 3,
skip = 4,
done = 5;
var label = start;
while (true){
var goTo = null;
switch (label){
case start:
console.log('start');
case more:
console.log('more');
case pass:
console.log('pass');
case loop:
console.log('loop');
goTo = pass; break;
case skip:
console.log('skip');
case done:
console.log('done');
}
if (goTo == null) break;
label = goTo;
}
Run Code Online (Sandbox Code Playgroud)
soe*_*ard 12
这是一个老问题,但由于JavaScript是一个移动目标 - 在ES6上可以实现支持正确的尾调用.在支持正确尾调用的实现上,您可以拥有无限数量的活动尾调用(即尾调用不会"增加堆栈").
A goto可以被认为是没有参数的尾调用.
这个例子:
start: alert("RINSE");
alert("LATHER");
goto start
Run Code Online (Sandbox Code Playgroud)
可写成
function start() { alert("RINSE");
alert("LATHER");
return start() }
Run Code Online (Sandbox Code Playgroud)
这里的调用start位于尾部位置,因此不会有堆栈溢出.
这是一个更复杂的例子:
label1: A
B
if C goto label3
D
label3: E
goto label1
Run Code Online (Sandbox Code Playgroud)
首先,我们将源分成块.每个标签表示新块的开始.
Block1
label1: A
B
if C goto label3
D
Block2
label3: E
goto label1
Run Code Online (Sandbox Code Playgroud)
我们需要使用gotos将块绑定在一起.在示例中,块E跟随D,因此我们goto label3在D之后添加一个.
Block1
label1: A
B
if C goto label2
D
goto label2
Block2
label2: E
goto label1
Run Code Online (Sandbox Code Playgroud)
现在每个块都成为一个函数,每个goto变成一个尾调用.
function label1() {
A
B
if C then return( label2() )
D
return( label2() )
}
function label2() {
E
return( label1() )
}
Run Code Online (Sandbox Code Playgroud)
要启动该程序,请使用label1().
重写纯粹是机械的,因此可以使用宏系统,如sweet.js,如果需要的话.
怎么样一个for循环?根据需要重复多次.或while循环,重复直到满足条件.有控制结构可以让你重复代码.我记得GOTO在Basic ...它编写了这么糟糕的代码!现代编程语言为您提供了实际可以维护的更好选择.
有一种方法可以做到,但需要仔细规划.以下面的QBASIC程序为例:
1 A = 1; B = 10;
10 print "A = ",A;
20 IF (A < B) THEN A = A + 1; GOTO 10
30 PRINT "That's the end."
Run Code Online (Sandbox Code Playgroud)
然后创建JavaScript以首先初始化所有变量,然后进行初始函数调用以开始滚动(我们在结束时执行此初始函数调用),并为您知道将在其中执行的每组行设置函数一个单位.
按照这个初始函数调用...
var a, b;
function fa(){
a = 1;
b = 10;
fb();
}
function fb(){
document.write("a = "+ a + "<br>");
fc();
}
function fc(){
if(a<b){
a++;
fb();
return;
}
else
{
document.write("That's the end.<br>");
}
}
fa();
Run Code Online (Sandbox Code Playgroud)
这个例子的结果是:
a = 1
a = 2
a = 3
a = 4
a = 5
a = 6
a = 7
a = 8
a = 9
a = 10
That's the end.
Run Code Online (Sandbox Code Playgroud)
一般来说,我不喜欢使用GoTo来提高可读性.对我来说,这是编写简单迭代函数的一个不好的借口,而不是编写递归函数,甚至更好(如果担心Stack Overflow之类的东西),它们真正的迭代替代方案(有时可能很复杂).
这样的事情会做:
while(true) {
alert("RINSE");
alert("LATHER");
}
Run Code Online (Sandbox Code Playgroud)
那就是无限循环.while子句的parantheses中的表达式("true")是Javascript引擎将检查的 - 如果表达式为true,它将保持循环运行.在这里写"true"总是评估为true,因此是无限循环.
当然,使用该switch构造您可以goto在JavaScript中进行仿真。不幸的是,该语言没有提供goto,但这已经足够替代。
let counter = 10
function goto(newValue) {
counter = newValue
}
while (true) {
switch (counter) {
case 10: alert("RINSE")
case 20: alert("LATHER")
case 30: goto(10); break
}
}
Run Code Online (Sandbox Code Playgroud)
你或许应该阅读一些JS教程这样的一个.
不确定是否goto存在于JS中,但无论如何,它都会鼓励编码风格错误,应该避免使用.
你可以这样做:
while ( some_condition ){
alert('RINSE');
alert('LATHER');
}
Run Code Online (Sandbox Code Playgroud)