[javascript] How can I use goto in Javascript?

I have some code that I absolutely must implement using goto. For example, I want to write a program like this:

start:
alert("RINSE");
alert("LATHER");
repeat: goto start

Is there a way to do that in Javascript?

This question is related to javascript goto

The answer is


Generally, I'd prefer not using GoTo for bad readability. To me, it's a bad excuse for programming simple iterative functions instead of having to program recursive functions, or even better (if things like a Stack Overflow is feared), their true iterative alternatives (which may sometimes be complex).

Something like this would do:

while(true) {
   alert("RINSE");
   alert("LATHER");
}

That right there is an infinite loop. The expression ("true") inside the parantheses of the while clause is what the Javascript engine will check for - and if the expression is true, it'll keep the loop running. Writing "true" here always evaluates to true, hence an infinite loop.


There is a way this can be done, but it needs to be planned carefully. Take for example the following QBASIC program:

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."

Then create your JavaScript to initialize all variables first, followed by making an initial function call to start the ball rolling (we execute this initial function call at the end), and set up functions for every set of lines that you know will be executed in the one unit.

Follow this with the initial function call...

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();

The result in this instance is:

a = 1
a = 2
a = 3
a = 4
a = 5
a = 6
a = 7
a = 8
a = 9
a = 10
That's the end.

This is an old question, but since JavaScript is a moving target - it is possible in ES6 on implementation that support proper tail calls. On implementations with support for proper tail calls, you can have an unbounded number of active tail calls (i.e. tail calls doesn't "grow the stack").

A goto can be thought of as a tail call with no parameters.

The example:

start: alert("RINSE");
       alert("LATHER");
       goto start

can be written as

 function start() { alert("RINSE");
                    alert("LATHER");
                    return start() }

Here the call to start is in tail position, so there will be no stack overflows.

Here is a more complex example:

 label1:   A
           B
           if C goto label3
           D
 label3:   E
           goto label1

First, we split the source up into blocks. Each label indicates the start of a new block.

 Block1
     label1:   A
               B
               if C goto label3
               D

  Block2    
     label3:   E
               goto label1

We need to bind the blocks together using gotos. In the example the block E follows D, so we add a goto label3 after D.

 Block1
     label1:   A
               B
               if C goto label2
               D
               goto label2

  Block2    
     label2:   E
               goto label1

Now each block becomes a function and each goto becomes a tail call.

 function label1() {
               A
               B
               if C then return( label2() )
               D
               return( label2() )
 }

 function label2() {
               E
               return( label1() )
 }

To start the program, use label1().

The rewrite is purely mechanical and can thus be done with a macro system such as sweet.js if need be.


You should probably read some JS tutorials like this one.

Not sure if goto exists in JS at all, but, either way, it encourages bad coding style and should be avoided.

You could do:

while ( some_condition ){
    alert('RINSE');
    alert('LATHER');
}

Another alternative way to achieve the same is to use the tail calls. But, we don’t have anything like that in JavaScript. So generally, the goto is accomplished in JS using the below two keywords. break and continue, reference: Goto Statement in JavaScript

Here is an example:

var number = 0;
start_position: while(true) {
document.write("Anything you want to print");
number++;
if(number < 100) continue start_position;
break;
}

You can simple use a function:

function hello() {
    alert("RINSE");
    alert("LATHER");
    hello();
}

goto begin and end of all parents closures

var foo=false;
var loop1=true;
LABEL1: do {var LABEL1GOTO=false;
    console.log("here be 2 times");
    if (foo==false){
        foo=true;
        LABEL1GOTO=true;continue LABEL1;// goto up
    }else{
        break LABEL1; //goto down
    }
    console.log("newer go here");
} while(LABEL1GOTO);

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;
}

In classic JavaScript you need to use do-while loops to achieve this type of code. I presume you are maybe generating code for some other thing.

The way to do it, like for backending bytecode to JavaScript is to wrap every label target in a "labelled" 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);

Every labelled do-while loop you use like this actually creates the two label points for the one label. One at the the top and one at the end of the loop. Jumping back uses continue and jumping forwards uses break.

// 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)

Unfortunately there is no other way to do it.

Normal Example Code:

while (x < 10 && Ok) {
  z = 0;
  while (z < 10) {
    if (!DoStuff()) {
      Ok = FALSE;
      break;
    }
    z++;
  }
  x++;
} 

So say the code gets encoded to bytecodes so now you must put the bytecodes into JavaScript to simulate your backend for some purpose.

JavaScript style:

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)

So using this technique does the job fine for simple purposes. Other than that not much else you can do.

For normal Javacript you should not need to use goto ever, so you should probably avoid this technique here unless you are specificaly translating other style code to run on JavaScript. I assume that is how they get the Linux kernel to boot in JavaScript for example.

NOTE! This is all naive explanation. For proper Js backend of bytecodes also consider examining the loops before outputting the code. Many simple while loops can be detected as such and then you can rather use loops instead of goto.


To achieve goto-like functionality while keeping the call stack clean, I am using this method:

// in other languages:
// tag1:
// doSomething();
// tag2:
// doMoreThings();
// if (someCondition) goto tag1;
// if (otherCondition) goto tag2;

function tag1() {
    doSomething();
    setTimeout(tag2, 0); // optional, alternatively just tag2();
}

function tag2() {
    doMoreThings();
    if (someCondition) {
        setTimeout(tag1, 0); // those 2 lines
        return;              // imitate goto
    }
    if (otherCondition) {
        setTimeout(tag2, 0); // those 2 lines
        return;              // imitate goto
    }
    setTimeout(tag3, 0); // optional, alternatively just tag3();
}

// ...

Please note that this code is slow since the function calls are added to timeouts queue, which is evaluated later, in browser's update loop.

Please also note that you can pass arguments (using setTimeout(func, 0, arg1, args...) in browser newer than IE9, or setTimeout(function(){func(arg1, args...)}, 0) in older browsers.

AFAIK, you shouldn't ever run into a case that requires this method unless you need to pause a non-parallelable loop in an environment without async/await support.


// example of goto in javascript:

var i, j;
loop_1:
    for (i = 0; i < 3; i++) { //The first for statement is labeled "loop_1"
        loop_2:
            for (j = 0; j < 3; j++) { //The second for statement is labeled "loop_2"
                if (i === 1 && j === 1) {
                    continue loop_1;
                }
                console.log('i = ' + i + ', j = ' + j);
            }
        }

No. They did not include that in ECMAScript:

ECMAScript has no goto statement.


How about a for loop? Repeat as many times as you like. Or a while loop, repeat until a condition is met. There are control structures that will let you repeat code. I remember GOTO in Basic... it made such bad code! Modern programming languages give you better options that you can actually maintain.


Sure, using the switch construct you can simulate goto in JavaScript. Unfortunately, the language doesn't provide goto, but this is a good enough of a replacement.

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
  }
}

Actually, I see that ECMAScript (JavaScript) DOES INDEED have a goto statement. However, the JavaScript goto has two flavors!

The two JavaScript flavors of goto are called labeled continue and labeled break. There is no keyword "goto" in JavaScript. The goto is accomplished in JavaScript using the break and continue keywords.

And this is more or less explicitly stated on the w3schools website here http://www.w3schools.com/js/js_switch.asp.

I find the documentation of the labeled continue and labeled break somewhat awkwardly expressed.

The difference between the labeled continue and labeled break is where they may be used. The labeled continue can only be used inside a while loop. See w3schools for some more information.

===========

Another approach that will work is to have a giant while statement with a giant switch statement inside:

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. ...
    }

}