Mam kod, który absolutnie muszę zaimplementować przy użyciu goto
. Na przykład chcę napisać taki program:
start:
alert("RINSE");
alert("LATHER");
repeat: goto start
Czy można to zrobić w Javascript?
javascript
goto
Peter Olson
źródło
źródło
Odpowiedzi:
Absolutnie! Istnieje projekt o nazwie Summer of Goto, który pozwala na wykorzystanie pełnego potencjału JavaScript i zrewolucjonizuje sposób pisania kodu.
To narzędzie do wstępnego przetwarzania JavaScript umożliwia utworzenie etykiety, a następnie przejście do niej przy użyciu następującej składni:
Na przykład przykład w pytaniu można zapisać w następujący sposób:
Zwróć uwagę, że nie jesteś ograniczony tylko do prostych, trywialnych programów, takich jak niekończący się
LATHER
RINSE
cykl powtarzania - możliwości, jakie daje,goto
są nieskończone i możesz nawetHello, world!
wysłać wiadomość do konsoli JavaScript 538 razy, na przykład:Możesz przeczytać więcej o implementacji goto , ale zasadniczo wykonuje on pewne wstępne przetwarzanie JavaScript, które wykorzystuje fakt, że możesz symulować goto za pomocą oznaczonej
while
pętli . Tak więc, pisząc „Hello, world!” program powyżej, zostanie przetłumaczony na coś takiego:Istnieją pewne ograniczenia tego procesu wstępnego przetwarzania, ponieważ pętle while nie mogą rozciągać się na wiele funkcji lub bloków. Nie jest to jednak wielka sprawa - jestem pewien, że korzyści płynące z możliwości korzystania z
goto
JavaScript absolutnie cię przytłoczy.Cały powyższy link prowadzący do biblioteki goto.js to ALL DEAD, tutaj potrzebne są linki:
goto.js (nieskompresowany) --- parseScripts.js (nieskompresowany)
Z Goto.js :
źródło
goto
prawdopodobnie jest niewykorzystany. To tworzy bardzo ładne wzorce obsługi błędów. Cholera, używamyswitch
, co jestgoto
w ogóle poza nazwą i nikt nie boli brzucha.Nie. Nie uwzględnili tego w ECMAScript:
źródło
goto
idealnie pasowałoby do koktajlu głupich "cech" javascript :)goto
jest jednak zastrzeżonym słowem kluczowym do użytku w przyszłości. Możemy tylko mieć nadzieję :)goto
przydałoby się, gdy chcesz powrócić z funkcji zagnieżdżonej. Na przykład, używając podkreślenia underscore.js, udostępniasz anonimową funkcję podczas iteracji po tablicach. Nie możesz wrócić z wnętrza takiej funkcji, więcgoto end;
byłoby przydatne.Właściwie widzę, że ECMAScript (JavaScript) CZY INDEED ma instrukcję goto. Jednak JavaScript goto ma dwa smaki!
Dwie odmiany goto w JavaScript są nazywane etykietami kontynuacji i przerwania. W JavaScript nie ma słowa kluczowego „goto”. Goto jest wykonywane w JavaScript przy użyciu słów kluczowych break i continue.
Jest to mniej więcej wyraźnie określone na stronie w3schools tutaj http://www.w3schools.com/js/js_switch.asp .
Uważam, że dokumentacja oznaczona jako kontynuacja i oznaczona jako przerwa jest nieco niezręcznie wyrażona.
Różnica między oznaczoną kontynuacją a oznaczoną przerwą polega na tym, gdzie można ich użyć. Oznaczony ciąg dalszy może być używany tylko w pętli while. Zobacz w3schools po więcej informacji.
===========
Innym podejściem, które zadziała, jest gigantyczne oświadczenie while z gigantycznym oświadczeniem przełącznika w środku:
źródło
break
icontinue
mogą być używane również wfor
pętlach. Ale tak naprawdę nie są one równoważnegoto
z założeniem, że są zamknięte w strukturze powiązanej pętli (pętli), w porównaniu zgoto
którą oczywiście - w językach, które ją mają - przenoszą się gdziekolwiek.W klasycznym JavaScript do osiągnięcia tego typu kodu potrzebne są pętle do-while. Zakładam, że być może generujesz kod do czegoś innego.
Sposobem na zrobienie tego, podobnie jak przy zapisywaniu kodu bajtowego w JavaScript, jest umieszczenie każdego celu etykiety w „oznaczonym” do-while.
Każda oznaczona pętla do-while, której używasz w ten sposób, w rzeczywistości tworzy dwa punkty etykiety dla jednej etykiety. Jeden na górze i jeden na końcu pętli. Skakanie do tyłu używa kontynuacji, a skok do przodu używa przerwy.
Niestety nie ma innej możliwości.
Normalny przykładowy kod:
Powiedzmy, że kod zostaje zakodowany do kodu bajtowego, więc teraz musisz umieścić kody bajtowe w JavaScript, aby symulować swój backend w jakimś celu.
Styl JavaScript:
Więc użycie tej techniki działa dobrze w prostych celach. Poza tym niewiele więcej możesz zrobić.
W przypadku normalnego Javacript nie powinieneś używać goto ever, więc prawdopodobnie powinieneś unikać tej techniki tutaj, chyba że tłumaczysz konkretnie inny kod stylu, aby działał w JavaScript. Zakładam, że w ten sposób na przykład pobierają jądro Linuksa w JavaScript.
UWAGA! To wszystko jest naiwne wyjaśnienie. Aby uzyskać poprawne zaplecze kodu bajtowego w języku Js, należy również rozważyć sprawdzenie pętli przed wyprowadzeniem kodu. Wiele prostych pętli while można wykryć jako takich, a następnie możesz raczej użyć pętli zamiast goto.
źródło
continue
wdo ... while
pętli kontynuuje warunek sprawdzenia . W ten sposóbgoto
użycie wstecznego tutajdo ... while (0)
nie działa. ecma-international.org/ecma-262/5.1/#sec-12.6.1let doLoop
to zadziałało. I główna pętla:let doLoop = false; do { if(condition){ doLoop = true; continue; } } while (doLoop)
github.com/patarapolw/HanziLevelUp/blob/ ...To stare pytanie, ale skoro JavaScript jest ruchomym celem - w ES6 jest to możliwe w przypadku implementacji obsługującej właściwe wywołania ogonowe. W implementacjach z obsługą poprawnych wywołań ogonowych, możesz mieć nieograniczoną liczbę aktywnych wywołań ogonowych (tj. Wywołania ogonowe nie „powiększają stosu”).
ZA
goto
Można traktować jako wezwanie ogonowej bez parametrów.Przykład:
można zapisać jako
Tutaj call do
start
jest na pozycji taila, więc nie będzie przepełnienia stosu.Oto bardziej złożony przykład:
Najpierw podzieliliśmy źródło na bloki. Każda etykieta wskazuje początek nowego bloku.
Musimy połączyć bloki razem za pomocą goto. W przykładzie blok E następuje po D, więc dodajemy a
goto label3
po D.Teraz każdy blok staje się funkcją, a każde goto staje się wywołaniem końcowym.
Aby uruchomić program, użyj
label1()
.Przepisanie jest czysto mechaniczne i można je w razie potrzeby wykonać za pomocą systemu makr, takiego jak sweet.js.
źródło
źródło
Co powiesz na
for
pętlę? Powtarzaj tyle razy, ile chcesz. Lubwhile
pętla, powtarzaj, aż warunek zostanie spełniony. Istnieją struktury kontrolne, które pozwolą Ci powtórzyć kod. Pamiętam, żeGOTO
w Basicu ... zrobił taki zły kod! Nowoczesne języki programowania zapewniają lepsze opcje, które możesz w rzeczywistości obsługiwać.źródło
Można to zrobić, ale należy to starannie zaplanować. Weźmy na przykład następujący program QBASIC:
Następnie utwórz JavaScript, aby najpierw zainicjować wszystkie zmienne, a następnie wykonaj początkowe wywołanie funkcji, aby rozpocząć przewijanie piłki (wykonujemy to początkowe wywołanie funkcji na końcu) i skonfiguruj funkcje dla każdego zestawu linii, o których wiesz, że zostaną wykonane w jedna jednostka.
Postępuj zgodnie z tym z początkowym wywołaniem funkcji ...
Wynik w tym przypadku to:
źródło
Generalnie wolałbym nie używać GoTo ze względu na słabą czytelność. Dla mnie jest to zła wymówka dla programowania prostych funkcji iteracyjnych zamiast konieczności programowania funkcji rekurencyjnych, a nawet lepiej (jeśli obawiamy się takich rzeczy jak przepełnienie stosu), ich prawdziwych iteracyjnych alternatyw (które czasami mogą być złożone).
Coś takiego zrobiłoby:
To właśnie jest nieskończona pętla. Wyrażenie („prawda”) w parantezach klauzuli while jest tym, co silnik JavaScript będzie sprawdzał - a jeśli wyrażenie jest prawdziwe, pętla będzie działać. Zapisanie tutaj „prawda” zawsze daje wartość „prawda”, stąd nieskończona pętla.
źródło
Jasne, używając
switch
konstrukcji, którą możesz zasymulowaćgoto
w JavaScript. Niestety język nie zapewniagoto
, ale jest to wystarczająca wymiana.źródło
Powinieneś przeczytać kilka tutoriali JS jak ten jeden .
Nie jestem pewien, czy
goto
w ogóle istnieje w JS, ale tak czy inaczej, zachęca to do złego stylu kodowania i należy go unikać.Mógłbyś:
źródło
Możesz w prosty sposób użyć funkcji:
źródło
Aby uzyskać funkcjonalność podobną do goto, zachowując czystość stosu wywołań, używam tej metody:
Należy pamiętać, że ten kod działa wolno, ponieważ wywołania funkcji są dodawane do kolejki limitów czasu, która jest oceniana później, w pętli aktualizacji przeglądarki.
Pamiętaj również, że możesz przekazywać argumenty (używając
setTimeout(func, 0, arg1, args...)
w przeglądarce nowszej niż IE9 lubsetTimeout(function(){func(arg1, args...)}, 0)
w starszych przeglądarkach.AFAIK, nigdy nie powinieneś natrafiać na przypadek, który wymaga tej metody, chyba że musisz wstrzymać nierównoległą pętlę w środowisku bez obsługi async / await.
źródło
zaczynam i kończą wszystkie zamknięcia rodziców
źródło
źródło
Innym alternatywnym sposobem osiągnięcia tego samego jest użycie wywołań ogonowych. Ale nie mamy czegoś takiego w JavaScript. Ogólnie rzecz biorąc, goto jest wykonywane w JS przy użyciu poniższych dwóch słów kluczowych. przerwij i kontynuuj , odniesienie: Goto Statement w JavaScript
Oto przykład:
źródło