¿Cómo puedo usar goto en Javascript?
Tengo un código que absolutamente debo implementar usando goto
. Por ejemplo, quiero escribir un programa como este:
start:
alert("RINSE");
alert("LATHER");
repeat: goto start
¿Hay alguna manera de hacer eso en Javascript?
14 answers
Absolutamente! Hay un proyecto llamado Summer of Goto que te permite usar JavaScript en su máximo potencial y revolucionará la forma en que puedes escribir tu código.
Esta herramienta de preprocesamiento de JavaScript le permite crear una etiqueta y luego ir usando esta sintaxis:
[lbl] <label-name>
goto <label-name>
Por ejemplo, el ejemplo de la pregunta se puede escribir de la siguiente manera:
[lbl] start:
alert("LATHER");
alert("RINSE");
[lbl] repeat: goto start;
Tenga en cuenta que no se limita a simples programas triviales como un endless LATHER
RINSE
repeat cycle-las posibilidades que ofrece goto
son infinitas e incluso puede hacer un mensaje Hello, world!
a la consola JavaScript 538 veces, como esto:
var i = 0;
[lbl] start:
console.log("Hello, world!");
i++;
if(i < 538) goto start;
Puede leer más sobre cómo se implementa goto, pero básicamente, hace un preprocesamiento de JavaScript que aprovecha el hecho de que puede simular un goto con un etiquetado while
loop. Entonces, cuando escribes el " Hola, mundo!"programa anterior, se traduce a algo como esto:
var i = 0;
start: while(true) {
console.log("Hello, world!");
i++;
if(i < 538) continue start;
break;
}
Hay algunas limitaciones a este proceso de preprocesamiento, porque los bucles while no pueden extenderse a través de múltiples funciones o bloques. Eso no es un gran problema, sin embargo, estoy seguro de que los beneficios de poder aprovechar goto
en JavaScript lo abrumarán absolutamente.
Todos los enlaces anteriores que conducen a goto.la biblioteca js está MUERTA, aquí hay enlaces necesarios:
Goto.js (sin comprimir) --- parseScripts.js (sin comprimir)
De Goto.js :
P.d. Para cualquiera que se pregunte (hasta ahora un total de cero personas), Summer of Goto es un término que fue popularizado por Paul Irish, mientras discutía este script y la decisión de PHP de agregar goto a su lenguaje.
Y para aquellos que no reconocen inmediatamente que todo esto es una broma, por favor perdónenme.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-12 03:32:47
No. No incluyeron eso en ECMAScript:
ECMAScript no tiene instrucción goto.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-17 15:31:08
En realidad, veo que ECMAScript (JavaScript) TIENE UNA sentencia goto. Sin embargo, el goto JavaScript tiene dos sabores!
Los dos tipos de JavaScript de goto se llaman etiquetados continue y etiquetados break. No hay ninguna palabra clave "goto" en JavaScript. El goto se logra en JavaScript usando las palabras clave break y continue.
Y esto se indica más o menos explícitamente en el sitio web de w3schools aquí http://www.w3schools.com/js/js_switch.asp .
I encontrar la documentación de la etiquetada continuar y etiquetado romper algo torpemente expresado.
La diferencia entre el continuar etiquetado y el descanso etiquetado es donde se pueden usar. La etiqueta continue solo se puede usar dentro de un bucle while. Vea w3schools para más información.
===========
Otro enfoque que funcionará es tener una sentencia giant while con una sentencia giant switch dentro:
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. ...
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-05 19:49:39
En JavaScript clásico necesita usar bucles do-while para lograr este tipo de código. Supongo que tal vez estás generando código para alguna otra cosa.
La forma de hacerlo, como para backending bytecode a JavaScript es envolver cada destino de etiqueta en un do-while "etiquetado".
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);
Cada bucle do-while etiquetado que utilices de esta manera crea los dos puntos de etiqueta para una etiqueta. Uno en la parte superior y otro al final del bucle. Jumping back usos continuar y saltar forwards usa 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)
Desafortunadamente no hay otra manera de hacerlo.
Código de ejemplo normal:
while (x < 10 && Ok) {
z = 0;
while (z < 10) {
if (!DoStuff()) {
Ok = FALSE;
break;
}
z++;
}
x++;
}
Así que digamos que el código se codifica en bytecodes por lo que ahora debe poner los bytecodes en JavaScript para simular su backend para algún propósito.
Estilo 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)
Así que el uso de esta técnica hace el trabajo bien para fines simples. Aparte de eso, no hay mucho más que puedas hacer.
Para Javacript normal no debería necesitar usar goto nunca, por lo que probablemente debería evitar esta técnica aquí a menos que esté traduciendo específicamente otro código de estilo para ejecutarse en JavaScript. Supongo que así es como consiguen que el kernel de Linux arranque en JavaScript, por ejemplo.
NOTA! Todo esto es una explicación ingenua. Para un backend Js apropiado de bytecodes también considere examinar los bucles antes de emitir el código. Muchos bucles while simples se pueden detectar como tales y luego puede usar bucles en lugar de goto.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-24 09:38:44
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;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-05 20:16:25
¿Qué tal un bucle for
? Repite tantas veces como quieras. O un bucle while
, repita hasta que se cumpla una condición. Hay estructuras de control que le permitirán repetir código. Recuerdo GOTO
en Basic... ¡hizo un código tan malo! Los lenguajes de programación modernos te dan mejores opciones que puedes mantener.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-17 15:32:35
Esta es una pregunta antigua, pero dado que JavaScript es un objetivo en movimiento, es posible en ES6 en implementación que admita llamadas de cola adecuadas. En implementaciones con soporte para llamadas tail adecuadas, puede tener un número ilimitado de llamadas tail activas (es decir, las llamadas tail no "hacen crecer la pila").
Un goto
puede ser considerado como una llamada de cola sin parámetros.
El ejemplo:
start: alert("RINSE");
alert("LATHER");
goto start
Se Puede escribir como
function start() { alert("RINSE");
alert("LATHER");
return start() }
Aquí la llamada a start
está en cola posición, por lo que no habrá desbordamientos de pila.
Aquí hay un ejemplo más complejo:
label1: A
B
if C goto label3
D
label3: E
goto label1
Primero, dividimos la fuente en bloques. Cada etiqueta indica el inicio de un nuevo bloque.
Block1
label1: A
B
if C goto label3
D
Block2
label3: E
goto label1
Necesitamos unir los bloques usando gotos.
En el ejemplo el bloque E sigue a D, así que añadimos a goto label3
después de D.
Block1
label1: A
B
if C goto label2
D
goto label2
Block2
label2: E
goto label1
Ahora cada bloque se convierte en una función y cada goto se convierte en una llamada de cola.
function label1() {
A
B
if C then return( label2() )
D
return( label2() )
}
function label2() {
E
return( label1() )
}
Para iniciar el programa, utilice label1()
.
El la reescritura es puramente mecánica y, por lo tanto, se puede hacer con un sistema macro como sweet.js si es necesario.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-16 04:53:13
Hay una manera de hacer esto, pero necesita ser planeado cuidadosamente. Tomemos por ejemplo el siguiente programa 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."
Luego cree su JavaScript para inicializar todas las variables primero, seguido de hacer una llamada a la función inicial para iniciar el balanceo de la bola (ejecutamos esta llamada a la función inicial al final), y configure funciones para cada conjunto de líneas que sepa que se ejecutarán en la unidad única.
Siga esto con la llamada a la función inicial...
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();
El el resultado en esta instancia es:
a = 1
a = 2
a = 3
a = 4
a = 5
a = 6
a = 7
a = 8
a = 9
a = 10
That's the end.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-27 04:33:52
Probablemente deberías leer algunos tutoriales de JS como este uno.
No estoy seguro de si goto
existe en JS, pero, de cualquier manera, fomenta un mal estilo de codificación y debe evitarse.
Usted podría hacer:
while ( some_condition ){
alert('RINSE');
alert('LATHER');
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-17 15:31:38
En general, preferiría no usar GoTo para una mala legibilidad. Para mí, es una mala excusa para programar funciones iterativas simples en lugar de tener que programar funciones recursivas, o incluso mejor (si se teme cosas como un Desbordamiento de pila), sus verdaderas alternativas iterativas (que a veces pueden ser complejas).
Algo como esto haría:
while(true) {
alert("RINSE");
alert("LATHER");
}
Ese derecho hay un bucle infinito. La expresión ("true") dentro de las parantesis de la cláusula while es lo que el Javascript motor comprobará - y si la expresión es verdadera, mantendrá el bucle en funcionamiento. Escribir "verdadero" aquí siempre se evalúa como verdadero, de ahí un bucle infinito.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-21 14:34:29
Puede usar una función simple:
function hello() {
alert("RINSE");
alert("LATHER");
hello();
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-15 10:55:19
Ir a comenzar y terminar todos los cierres de padres
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);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-20 11:22:25
Para lograr una funcionalidad similar a goto mientras mantengo limpia la pila de llamadas, estoy usando este método:
// 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();
}
// ...
Tenga en cuenta que este código es lento ya que las llamadas a la función se agregan a la cola de tiempos de espera, que se evalúa más tarde, en el bucle de actualización del navegador.
También tenga en cuenta que puede pasar argumentos (usando setTimeout(func, 0, arg1, args...)
en un navegador más reciente que IE9, o setTimeout(function(){func(arg1, args...)}, 0)
en navegadores más antiguos.
AFAIK, nunca debería encontrarse con un caso que requiera este método a menos que necesite pausar un bucle no paralelable en un entorno sin soporte async / await.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-09 16:30:25
Claro, usando la construcción switch
puede simular goto
en JavaScript. Desafortunadamente, el lenguaje no proporciona goto
, pero este es un reemplazo suficientemente bueno.
let counter = 10
function goto(newValue) {
counter = newValue
}
while (true) {
switch (counter) {
case 10: alert("RINSE")
case 20: alert("LATHER")
case 30: goto(10)
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-24 07:40:55