Ich habe einen Code, den ich unbedingt implementieren muss goto
. Zum Beispiel möchte ich ein Programm wie dieses schreiben:
start:
alert("RINSE");
alert("LATHER");
repeat: goto start
Gibt es eine Möglichkeit, dies in Javascript zu tun?
javascript
goto
Peter Olson
quelle
quelle
Antworten:
Absolut! Es gibt ein Projekt namens Summer of Goto , mit dem Sie JavaScript in vollem Umfang nutzen und die Art und Weise, wie Sie Ihren Code schreiben können, revolutionieren können.
Mit diesem JavaScript-Vorverarbeitungstool können Sie eine Beschriftung erstellen und diese dann mithilfe der folgenden Syntax aufrufen:
Das Beispiel in der Frage kann beispielsweise wie folgt geschrieben werden:
Beachten Sie, dass Sie sich nicht nur auf einfache triviale Programme wie einen endlosen
LATHER
RINSE
Wiederholungszyklus beschränken - die Möglichkeitengoto
sind endlos und Sie können sogarHello, world!
538 Mal eine Nachricht an die JavaScript-Konsole senden, wie folgt:Sie können mehr darüber lesen, wie goto implementiert wird , aber im Grunde führt es eine JavaScript-Vorverarbeitung durch, die die Tatsache ausnutzt, dass Sie ein goto mit einer beschrifteten
while
Schleife simulieren können . Also, wenn Sie die "Hallo Welt!" Programm oben, es wird in so etwas übersetzt:Dieser Vorverarbeitungsprozess unterliegt einigen Einschränkungen, da sich while-Schleifen nicht über mehrere Funktionen oder Blöcke erstrecken können. Das ist jedoch keine große Sache - ich bin sicher, dass die Vorteile,
goto
JavaScript nutzen zu können, Sie absolut überwältigen werden.Alle oben genannten Links, die zur goto.js-Bibliothek führen, sind ALL DEAD. Hier werden Links benötigt:
goto.js (unkomprimiert) --- parseScripts.js (unkomprimiert)
Von Goto.js :
quelle
goto
es wahrscheinlich nicht ausreichend genutzt wird. Dies führt zu einigen sehr schönen Fehlerbehandlungsmustern. Heck, wir verwendenswitch
, wasgoto
in allen außer Namen ist, und niemand Bauchschmerzen.Nein, sie haben das nicht in ECMAScript aufgenommen:
quelle
goto
würde einfach perfekt in Javascript Cocktail von dummen "Features" passen :)goto
ist jedoch ein reserviertes Schlüsselwort für die zukünftige Verwendung. Wir können nur hoffen :)goto
wäre nützlich, wenn Sie von einer verschachtelten Funktion zurückkehren möchten. Wenn Sie beispielsweise underscore.js verwenden, stellen Sie eine anonyme Funktion bereit, wenn Sie über Arrays iterieren. Sie können innerhalb einer solchen Funktion nicht zurückkehren, diesgoto end;
wäre also nützlich.Eigentlich sehe ich, dass ECMAScript (JavaScript) DOES INDEED eine goto-Anweisung hat. Das JavaScript goto hat jedoch zwei Varianten!
Die beiden JavaScript-Varianten von goto heißen "continue" und "break". In JavaScript gibt es kein Schlüsselwort "goto". Das Goto wird in JavaScript mit den Schlüsselwörtern break und continue ausgeführt.
Und dies wird mehr oder weniger explizit auf der Website von w3schools hier http://www.w3schools.com/js/js_switch.asp angegeben .
Ich finde die Dokumentation der beschrifteten Fortsetzung und beschrifteten Pause etwas umständlich ausgedrückt.
Der Unterschied zwischen der beschrifteten Fortsetzung und der beschrifteten Unterbrechung besteht darin, wo sie verwendet werden können. Das beschriftete Fortsetzen kann nur innerhalb einer while-Schleife verwendet werden. Weitere Informationen finden Sie unter w3schools.
===========
Ein anderer Ansatz, der funktionieren wird, besteht darin, eine riesige while-Anweisung mit einer riesigen switch-Anweisung zu haben:
quelle
break
undcontinue
kann auch infor
Schleifen verwendet werden. Aber sie sind wirklich nicht gleichbedeutend damitgoto
, dass sie in der Struktur der zugehörigen Schleife (n) eingeschlossen sind, im Vergleich dazugoto
können sie natürlich - in Sprachen, in denen sie vorhanden sind - überall hingehen.In klassischem JavaScript müssen Sie do-while-Schleifen verwenden, um diesen Codetyp zu erreichen. Ich nehme an, Sie generieren möglicherweise Code für eine andere Sache.
Die Art und Weise, dies zu tun, wie beim Backend von Bytecode in JavaScript, besteht darin, jedes Beschriftungsziel in eine "beschriftete" Aufgabe zu verpacken.
Jede beschriftete Do-While-Schleife, die Sie so verwenden, erstellt tatsächlich die beiden Beschriftungspunkte für die eine Beschriftung. Eine oben und eine am Ende der Schleife. Das Zurückspringen nutzt weiter und das Vorwärtsspringen benutzt Pause.
Leider gibt es keinen anderen Weg, dies zu tun.
Normaler Beispielcode:
Angenommen, der Code wird in Bytecodes codiert. Jetzt müssen Sie die Bytecodes in JavaScript einfügen, um Ihr Backend für einen bestimmten Zweck zu simulieren.
JavaScript-Stil:
Die Verwendung dieser Technik macht den Job also für einfache Zwecke gut. Davon abgesehen können Sie nicht viel anderes tun.
Für normales Javacript sollten Sie goto nie verwenden müssen, daher sollten Sie diese Technik hier wahrscheinlich vermeiden, es sei denn, Sie übersetzen speziell anderen Stilcode, der unter JavaScript ausgeführt werden soll. Ich gehe davon aus, dass der Linux-Kernel auf diese Weise beispielsweise in JavaScript gestartet wird.
HINWEIS! Das ist alles eine naive Erklärung. Für ein korrektes Js-Backend von Bytecodes sollten Sie auch die Schleifen untersuchen, bevor Sie den Code ausgeben. Viele einfache while-Schleifen können als solche erkannt werden, und dann können Sie lieber Schleifen anstelle von goto verwenden.
quelle
continue
in einerdo ... while
Schleife fährt mit der Prüfbedingung fort . Die Rückwärtsnutzunggoto
hierdo ... while (0)
funktioniert also nicht. ecma-international.org/ecma-262/5.1/#sec-12.6.1let doLoop
damit das funktioniert. Und Hauptschleife:let doLoop = false; do { if(condition){ doLoop = true; continue; } } while (doLoop)
github.com/patarapolw/HanziLevelUp/blob/…Dies ist eine alte Frage, aber da JavaScript ein sich bewegendes Ziel ist, ist es in ES6 bei der Implementierung möglich, dass ordnungsgemäße Tail-Aufrufe unterstützt werden. Bei Implementierungen mit Unterstützung für ordnungsgemäße Tail-Aufrufe können Sie eine unbegrenzte Anzahl aktiver Tail-Aufrufe haben (dh Tail-Aufrufe vergrößern den Stapel nicht).
A
goto
kann als Tail Call ohne Parameter betrachtet werden.Das Beispiel:
kann geschrieben werden als
Hier befindet sich der Aufruf von
start
in der Endposition, sodass keine Stapelüberläufe auftreten.Hier ist ein komplexeres Beispiel:
Zuerst teilen wir die Quelle in Blöcke auf. Jedes Etikett zeigt den Beginn eines neuen Blocks an.
Wir müssen die Blöcke mit gotos zusammenbinden. Im Beispiel folgt der Block E D, also fügen wir ein
goto label3
nach D hinzu.Jetzt wird jeder Block zu einer Funktion und jeder goto wird zu einem Tail Call.
Verwenden Sie zum Starten des Programms
label1()
.Das Umschreiben ist rein mechanisch und kann daher bei Bedarf mit einem Makrosystem wie sweet.js durchgeführt werden.
quelle
quelle
Wie wäre es mit einer
for
Schleife? Wiederholen Sie so oft Sie möchten. Oderwhile
wiederholen Sie eine Schleife, bis eine Bedingung erfüllt ist. Es gibt Kontrollstrukturen, mit denen Sie Code wiederholen können. Ich erinnere mich anGOTO
Basic ... es hat so einen schlechten Code gemacht! Moderne Programmiersprachen bieten Ihnen bessere Optionen, die Sie tatsächlich beibehalten können.quelle
Es gibt eine Möglichkeit, dies zu tun, aber es muss sorgfältig geplant werden. Nehmen Sie zum Beispiel das folgende QBASIC-Programm:
Erstellen Sie dann Ihr JavaScript, um zuerst alle Variablen zu initialisieren, gefolgt von einem ersten Funktionsaufruf, um den Ball ins Rollen zu bringen (wir führen diesen ersten Funktionsaufruf am Ende aus), und richten Sie Funktionen für jeden Satz von Zeilen ein, von denen Sie wissen, dass sie ausgeführt werden die eine Einheit.
Folgen Sie dem mit dem ersten Funktionsaufruf ...
Das Ergebnis in diesem Fall ist:
quelle
Im Allgemeinen würde ich GoTo wegen schlechter Lesbarkeit lieber nicht verwenden. Für mich ist es eine schlechte Ausrede, einfache iterative Funktionen zu programmieren, anstatt rekursive Funktionen programmieren zu müssen, oder noch besser (wenn Dinge wie ein Stapelüberlauf befürchtet werden), ihre wahren iterativen Alternativen (die manchmal komplex sein können).
So etwas würde reichen:
Genau dort gibt es eine Endlosschleife. Der Ausdruck ("true") in den Klammern der while-Klausel wird von der Javascript-Engine überprüft - und wenn der Ausdruck true ist, wird die Schleife weiter ausgeführt. Das Schreiben von "wahr" hier wird immer als wahr ausgewertet, daher eine Endlosschleife.
quelle
Sicher, mit dem
switch
Konstrukt können Siegoto
in JavaScript simulieren . Leider bietet die Sprache keinegoto
, aber dies ist ein guter Ersatz.quelle
Sie sollten wahrscheinlich einige JS - Tutorials wie diese lesen ein .
Ich bin mir nicht sicher, ob
goto
es überhaupt in JS existiert, aber in beiden Fällen fördert es einen schlechten Codierungsstil und sollte vermieden werden.Du könntest es tun:
quelle
Sie können einfach eine Funktion verwenden:
quelle
Um eine goto-ähnliche Funktionalität zu erreichen und gleichzeitig den Aufrufstapel sauber zu halten, verwende ich diese Methode:
Bitte beachten Sie, dass dieser Code langsam ist, da die Funktionsaufrufe der Timeout-Warteschlange hinzugefügt werden, die später in der Aktualisierungsschleife des Browsers ausgewertet wird.
Bitte beachten Sie auch, dass Sie Argumente übergeben können (
setTimeout(func, 0, arg1, args...)
in einem Browser, der neuer als IE9 ist, odersetTimeout(function(){func(arg1, args...)}, 0)
in älteren Browsern.AFAIK, Sie sollten niemals auf einen Fall stoßen, der diese Methode erfordert, es sei denn, Sie müssen eine nicht parallele Schleife in einer Umgebung ohne asynchrone / wartende Unterstützung anhalten.
quelle
gehe zu Beginn und Ende aller Schließungen der Eltern
quelle
quelle
Eine andere alternative Möglichkeit, dies zu erreichen, ist die Verwendung der Tail Calls. Aber so etwas haben wir in JavaScript nicht. Im Allgemeinen wird das Goto in JS mit den folgenden beiden Schlüsselwörtern ausgeführt. brechen und fortfahren , Referenz: Gehe zu Anweisung in JavaScript
Hier ist ein Beispiel:
quelle