回答:
絶対に!JavaScriptを最大限に活用し、コードの記述方法に革命をもたらす、Summer of Gotoというプロジェクトがあります。
このJavaScript前処理ツールを使用すると、ラベルを作成し、次の構文を使用してラベルに移動できます。
[lbl] <label-name>
goto <label-name>
たとえば、質問の例は次のように書くことができます。
[lbl] start:
alert("LATHER");
alert("RINSE");
[lbl] repeat: goto start;
エンドレスLATHER
RINSE
リピートサイクルのような単純な単純なプログラムだけに限定されているわけではないことに注意してください。これにより、可能性goto
は無限になりHello, world!
、JavaScriptコンソールに次のように538回メッセージを送信できます。
var i = 0;
[lbl] start:
console.log("Hello, world!");
i++;
if(i < 538) goto start;
gotoの実装方法について詳しく読むことができますが、基本的には、ラベル付きwhile
ループを使用してgotoをシミュレートできるという事実を利用するJavaScriptの前処理を行います。「Hello、world!」と書くと 上記のプログラムでは、次のように変換されます。
var i = 0;
start: while(true) {
console.log("Hello, world!");
i++;
if(i < 538) continue start;
break;
}
whileループは複数の関数またはブロックにまたがることができないため、この前処理プロセスにはいくつかの制限があります。ただし、それは大したことではありません。JavaScriptで利用できることの利点は、間違いなくgoto
あなたを圧倒します。
goto.jsライブラリにつながる上記のリンクはすべて死んでいます。必要なリンクは次のとおりです。
goto.js(非圧縮) ---圧縮)
Goto.jsから:
PS疑問に思っている人(これまでに合計で0人)にとって、Summer of Gotoは、このスクリプトとPHPによるgotoの言語への追加の決定について説明しながら、Paul Irishによって広まった用語です。
そして、このすべてが冗談であることをすぐに認識しない人のために、私を許してください。<—(保険)。
goto
おそらく十分に活用されていないと思います。それはいくつかの非常に素晴らしいエラー処理パターンになります。ヘック、私たちswitch
はgoto
名前を除いてすべてを使用し、誰も腹痛はありません。
ECMAScriptにはgotoステートメントがありません。
goto
は、javascriptの愚かな "機能"のカクテルにぴったり合うでしょう:)
goto
ただし、将来使用するために予約されているキーワードです。期待できるのは:)
goto
ネストされた関数から戻る場合に便利です。たとえば、underscore.jsを使用する場合、配列を反復するときに無名関数を提供します。このような関数の内部から戻ることはできないのでgoto end;
便利です。
実際、ECMAScript(JavaScript)には確かにgotoステートメントがあることがわかります。ただし、JavaScript gotoには2つのフレーバーがあります。
gotoの2つのJavaScriptフレーバーは、ラベル付き続行とラベル付きブレークと呼ばれます。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. ...
}
}
break
おりcontinue
、for
ループでも使用できます。しかし、それらが関連するループの構造にロックされていることを考えると、それらは実際には同等ではありません。もちろん、それを持っている言語では、どこにでも行くことができます。goto
goto
従来の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);
このように使用するすべてのラベル付きdo-whileループは、実際には1つのラベルに対して2つのラベルポイントを作成します。1つはループの上部にあり、もう1つはループの終わりにあります。後ろにジャンプする場合は続行を使用し、前にジャンプする場合は中断を使用します。
// 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)
残念ながらそれを行う他の方法はありません。
通常のコード例:
while (x < 10 && Ok) {
z = 0;
while (z < 10) {
if (!DoStuff()) {
Ok = FALSE;
break;
}
z++;
}
x++;
}
つまり、コードがバイトコードにエンコードされるとしましょう。そのため、バイトコードを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)
したがって、この手法を使用すると、単純な目的で問題なく機能します。それ以外にできることは他にあまりありません。
通常のJavacriptの場合、gotoを使用する必要はないので、JavaScriptで実行するために他のスタイルのコードを具体的に変換するのでない限り、ここではこの手法を回避する必要があります。私はそれが彼らがLinuxカーネルを例えばJavaScriptで起動させる方法だと思います。
注意!これはすべて単純な説明です。バイトコードの適切なJsバックエンドについては、コードを出力する前にループを調べることも検討してください。多くの単純なwhileループが検出されるため、gotoの代わりにループを使用できます。
continue
でdo ... while
ループ続けてチェック状態に。したがって、goto
ここでの逆方向の使用do ... while (0)
は機能しません。ecma-international.org/ecma-262/5.1/#sec-12.6.1
let doLoop
仕事に、このため。そして、メインループ:let doLoop = false; do { if(condition){ doLoop = true; continue; } } while (doLoop)
github.com/patarapolw/HanziLevelUp/blob/...
これは古い質問ですが、JavaScriptは動くターゲットなので、ES6では、適切な末尾呼び出しをサポートする実装が可能です。適切な末尾呼び出しをサポートする実装では、無制限の数のアクティブな末尾呼び出しを行うことができます(つまり、末尾呼び出しは「スタックを拡大」しません)。
あ goto
はパラメーターのない末尾呼び出しと考えることができます。
例:
start: alert("RINSE");
alert("LATHER");
goto start
次のように書くことができます
function start() { alert("RINSE");
alert("LATHER");
return start() }
ここでの呼び出しstart
は末尾の位置にあるため、スタックオーバーフローは発生しません。
次に、より複雑な例を示します。
label1: A
B
if C goto label3
D
label3: E
goto label1
まず、ソースをブロックに分割します。各ラベルは、新しいブロックの開始を示します。
Block1
label1: A
B
if C goto label3
D
Block2
label3: E
goto label1
gotosを使用してブロックを結合する必要があります。この例では、ブロックEがDのgoto label3
後に続いているため、後にD を追加しています。
Block1
label1: A
B
if C goto label2
D
goto label2
Block2
label2: E
goto label1
これで、各ブロックが関数になり、各gotoが末尾呼び出しになります。
function label1() {
A
B
if C then return( label2() )
D
return( label2() )
}
function label2() {
E
return( label1() )
}
プログラムを開始するには、 label1()
。
書き換えは純粋に機械的なものであるため、必要に応じてsweet.jsなどのマクロシステムを使用して行うことができます。
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;
}
どの程度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."
次に、最初にすべての変数を初期化するJavaScriptを作成してから、ボールのローリングを開始するための初期関数呼び出しを行い(最後にこの初期関数呼び出しを実行します)、実行されることがわかっているすべての行のセットに対して関数を設定します。 1つのユニット。
これに続いて、最初の関数呼び出しを行います...
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();
この場合の結果は次のとおりです。
a = 1
a = 2
a = 3
a = 4
a = 5
a = 6
a = 7
a = 8
a = 9
a = 10
That's the end.
一般的に、読みやすさを考慮してGoToは使用しないほうがよいでしょう。私にとって、それは再帰関数をプログラムする必要がある代わりに単純な反復関数をプログラミングするための悪い言い訳です。
このような何かがします:
while(true) {
alert("RINSE");
alert("LATHER");
}
その右には無限ループがあります。while句の括弧内の式( "true")は、JavaScriptエンジンがチェックするものであり、式がtrueの場合、ループを実行し続けます。ここで「true」を書き込むと、常にtrueに評価されるため、無限ループになります。
もちろん、JavaScriptでswitch
シミュレートできる構成体を使用goto
します。残念ながら、この言語はを提供していません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
}
}
あなたは、おそらくこのようないくつかのJSのチュートリアル読むべきものを。
goto
JSに存在するかどうかは不明ですが、いずれにしても、コーディングスタイルが悪いため、回避する必要があります。
あなたがすることができます:
while ( some_condition ){
alert('RINSE');
alert('LATHER');
}
呼び出しスタックをクリーンに保ちながらgotoのような機能を実現するために、私はこのメソッドを使用しています。
// 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();
}
// ...
関数呼び出しはタイムアウトキューに追加されるため、このコードは遅いことに注意してください。タイムアウトキューは、ブラウザーの更新ループで後で評価されます。
引数を渡すことができることにも注意してください(setTimeout(func, 0, arg1, args...)
IE9より新しいブラウザーまたはsetTimeout(function(){func(arg1, args...)}, 0)
古いブラウザーで使用)。
私の知る限り、非同期/待機サポートのない環境で並列化できないループを一時停止する必要がない限り、このメソッドを必要とするケースに遭遇すべきではありません。
// 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);
}
}
同じことを達成する別の代替方法は、末尾呼び出しを使用することです。しかし、JavaScriptにはそのようなものはありません。したがって、一般的に、gotoはJSで以下の2つのキーワードを使用して実行されます。 中断して 続行、参照:JavaScriptのGotoステートメント
次に例を示します。
var number = 0;
start_position: while(true) {
document.write("Anything you want to print");
number++;
if(number < 100) continue start_position;
break;
}