ฉันจะใช้ goto ใน Javascript ได้อย่างไร


127

gotoฉันมีรหัสบางอย่างที่ฉันอย่างจะต้องดำเนินการโดยใช้ ตัวอย่างเช่นฉันต้องการเขียนโปรแกรมดังนี้:

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

มีวิธีทำใน Javascript หรือไม่?


goto น่าจะสะดวกสำหรับจาวาสคริปต์ที่คอมไพล์ ฉันมี JVM ที่เขียนด้วย JavaScript มันจะเป็นนักแสดงมากและสั้นกว่าด้วยคำสั่ง goto
neoexpert

คำตอบ:


151

แน่นอน! มีโครงการชื่อSummer of Gotoที่ช่วยให้คุณใช้ JavaScript ได้อย่างเต็มประสิทธิภาพและจะปฏิวัติวิธีการเขียนโค้ดของคุณ

เครื่องมือก่อนการประมวลผล 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;

คุณสามารถอ่านเพิ่มเติมเกี่ยวกับวิธีการที่จะดำเนินการข้ามไปแต่โดยทั่วไปก็ไม่บาง preprocessing JavaScript ที่ใช้ประโยชน์จากความจริงที่ว่าคุณสามารถจำลองโกโตะที่มีการติดป้ายชื่อwhileวง ดังนั้นเมื่อคุณเขียนข้อความ "Hello, world!" โปรแกรมด้านบนจะได้รับการแปลเป็นดังนี้:

var i = 0;
start: while(true) {
  console.log("Hello, world!");
  i++;
  if(i < 538) continue start;
  break;
}

มีข้อ จำกัด บางประการสำหรับกระบวนการก่อนการประมวลผลนี้เนื่องจากในขณะที่ลูปไม่สามารถขยายข้ามฟังก์ชันหรือบล็อกต่างๆได้ นั่นไม่ใช่เรื่องใหญ่ แต่ฉันมั่นใจว่าประโยชน์ของการใช้ประโยชน์จากgotoJavaScript จะครอบงำคุณอย่างแน่นอน

ลิงก์ด้านบนทั้งหมดที่นำไปสู่ไลบรารี goto.js คือ DEAD ทั้งหมดนี่คือลิงค์ที่จำเป็น:

goto.js (ไม่บีบอัด) - parseScripts.js (ไม่บีบอัด)

จากGoto.js :

ป.ล. สำหรับใครก็ตามที่สงสัย (จนถึงขณะนี้มีคนเป็นศูนย์) Summer of Goto เป็นคำที่ Paul Irish ได้รับความนิยมในขณะที่พูดถึงสคริปต์นี้และการตัดสินใจของ PHP ในการเพิ่ม goto ลงในภาษาของพวกเขา

และสำหรับใครที่ไม่รู้ทันทีว่าเรื่องทั้งหมดนี้เป็นเรื่องตลกโปรดยกโทษให้ฉันด้วย <- (ประกันภัย)


10
@SurrealDreams มันอาจจะเป็นเรื่องตลก แต่มันใช้งานได้จริง คุณสามารถคลิกลิงก์ jsFiddle และดูว่าใช้งานได้จริง
Peter Olson

22
บทความที่คุณเชื่อมโยงไประบุว่าเป็นเรื่องตลก :)
pimvdb

6
@PeterOlson แต่ stackoverflow มีไว้เพื่อช่วยให้ผู้คนเรียนรู้การเขียนโปรแกรม คำถามและคำตอบควรเป็นประโยชน์ในการทำเช่นนั้นด้วย ไม่มีใครได้รับความช่วยเหลือจากสิ่งนี้
GoldenNewby

5
@ShadowWizard คำตอบนี้ถูกล้อมรอบไปด้วยข้อจำกัดความรับผิดชอบมากมายและมีคนพูดถึงสาเหตุที่ไม่ควรใช้ ฉันไม่รู้สึกอับอายที่ปล่อยให้คนที่เพิกเฉยต่อสิ่งนั้นต้องเผชิญกับผลของการทำเช่นนั้น
Peter Olson

8
+1 สำหรับ @AlexMills จริงๆแล้วฉันคิดว่าgotoอาจใช้ไม่ได้ผล ทำให้มีรูปแบบการจัดการข้อผิดพลาดที่ดีมาก ห่าเราใช้switchซึ่งมีgotoแต่ชื่อและไม่มีใครปวดท้อง
0x1mason

122

ไม่พวกเขาไม่ได้รวมไว้ใน ECMAScript:

ECMAScript ไม่มีคำสั่ง goto


1
ฉันสงสัยว่า GOTO จะมีประโยชน์ในขณะที่แก้จุดบกพร่อง JavaScript หรือไม่ Afaik มีเพียง IE เท่านั้นที่ให้ GOTO ในดีบักเกอร์ ... และจริงๆแล้วฉันก็พบ use-case สำหรับมัน แต่ฉันไม่แน่ใจว่าโดยทั่วไปแล้วจะมีประโยชน์หรือไม่ ... คุณคิดอย่างไร?
Šime Vidas

3
@ Šime Vidas: ฉันไม่แน่ใจว่าการดีบักด้วยฟังก์ชัน goto จะมีประโยชน์หรือไม่ โดยทั่วไปคุณจะยุ่งกับเส้นทางรหัสในแบบที่จะไม่เกิดขึ้นโดยไม่ต้องแก้ไขจุดบกพร่อง
pimvdb

12
ช่างน่าเสียดาย ... IMHO gotoจะเข้ากันได้ดีกับค็อกเทล "คุณสมบัติ" โง่ ๆ ของจาวาสคริปต์ :)
Yuriy Nakonechnyy

4
gotoเป็นคำหลักที่สงวนไว้สำหรับการใช้งานในอนาคตอย่างไรก็ตาม เราทำได้แค่หวัง :)
Azmisov

4
gotoจะมีประโยชน์เมื่อคุณต้องการกลับจากฟังก์ชันที่ซ้อนกัน ตัวอย่างเช่นเมื่อใช้ underscore.js คุณจะต้องระบุฟังก์ชันที่ไม่ระบุชื่อเมื่อทำซ้ำบนอาร์เรย์ คุณไม่สามารถกลับมาจากภายในฟังก์ชันดังกล่าวได้ดังนั้นgoto end;จะมีประโยชน์
Hubro

31

จริงๆแล้วฉันเห็นว่า ECMAScript (JavaScript) DOES INDEED มีคำสั่ง goto อย่างไรก็ตาม JavaScript goto มีสองรสชาติ!

goto สองรสชาติของ JavaScript เรียกว่าดำเนินการต่อและติดป้ายกำกับว่าแบ่ง ไม่มีคำหลัก "goto" ใน JavaScript goto สามารถทำได้ใน JavaScript โดยใช้ตัวแบ่งและดำเนินการต่อ

และนี่คือมากกว่าหรือน้อยกว่าที่ระบุไว้อย่างชัดเจนบนเว็บไซต์ w3schools นี่http://www.w3schools.com/js/js_switch.asp

ฉันพบเอกสารของการดำเนินการที่มีป้ายกำกับและมีป้ายกำกับว่า break ค่อนข้างแสดงออกอย่างเชื่องช้า

ความแตกต่างระหว่างตัวแบ่งที่มีป้ายกำกับว่าดำเนินการต่อและตัวแบ่งที่มีป้ายกำกับคือจุดที่อาจใช้ การดำเนินการที่มีป้ายกำกับสามารถใช้ได้ภายในลูป while เท่านั้น ดู w3schools สำหรับข้อมูลเพิ่มเติม

===========

อีกวิธีหนึ่งที่จะได้ผลคือการมีคำสั่ง Giant while พร้อมด้วยคำสั่งสวิตช์ยักษ์ภายใน:

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

}

9
"ดำเนินการต่อที่มีป้ายกำกับสามารถใช้ได้ภายในลูปในขณะที่" - ไม่ติดป้ายกำกับbreakและcontinueอาจใช้ในforลูปด้วย แต่จริงๆแล้วมันไม่เทียบเท่ากับการgotoที่พวกมันถูกล็อคไว้ในโครงสร้างของลูปที่เกี่ยวข้องเมื่อเทียบกับgotoที่แน่นอนในภาษาที่มีมันไปได้ทุกที่
nnnnnn

31

ใน JavaScript แบบคลาสสิกคุณต้องใช้ do-while loops เพื่อให้ได้โค้ดประเภทนี้ ฉันคิดว่าคุณอาจกำลังสร้างรหัสสำหรับสิ่งอื่น

วิธีการทำเช่นเดียวกับการแบ็กเอนด์โค้ดโค้ดไปยัง 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 ที่มีป้ายกำกับที่คุณใช้แบบนี้จะสร้างจุดฉลากสองจุดสำหรับป้ายกำกับเดียว หนึ่งอันที่ด้านบนและอีกอันที่ปลายลูป การกระโดดกลับใช้ต่อและกระโดดไปข้างหน้าใช้การหยุดพัก

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

สมมติว่ารหัสได้รับการเข้ารหัสเป็น bytecodes ดังนั้นตอนนี้คุณต้องใส่ bytecodes ลงใน 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 ที่เหมาะสมของ bytecodes ให้พิจารณาการตรวจสอบลูปก่อนที่จะส่งออกโค้ด หลายวิธีง่ายๆในขณะที่สามารถตรวจพบลูปได้จากนั้นคุณสามารถใช้ลูปแทน goto ได้


1
continueในdo ... whileวงยังคงสภาพการตรวจสอบ การย้อนกลับgotoที่นี่โดยใช้do ... while (0)จึงไม่ทำงาน ecma-international.org/ecma-262/5.1/#sec-12.6.1
ZachB

1
ไม่ทำงาน ฉันต้องlet doLoopทำสิ่งนี้ให้ได้ และลูปหลัก: let doLoop = false; do { if(condition){ doLoop = true; continue; } } while (doLoop) github.com/patarapolw/HanziLevelUp/blob/…
Polv

15

นี่เป็นคำถามเก่า แต่เนื่องจาก 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 ดังนั้นเราจึงเพิ่ม a 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 หากจำเป็น


"เป็นไปได้ใน ES6 ในการใช้งานที่รองรับการเรียกหางที่เหมาะสม" การเรียกหาง AFAIK ถูกปิดใช้งานในเบราว์เซอร์หลักทั้งหมด
JD

ฉันเชื่อว่า Safari รองรับการโทรหางที่เหมาะสม ในขณะที่ได้รับคำตอบคุณสามารถเปิดใช้งานการโทรหางที่ถูกต้องใน Chrome ผ่านสวิตช์บรรทัดคำสั่ง หวังว่าพวกเขาจะพิจารณาอีกครั้ง - หรืออย่างน้อยก็เริ่มรองรับการเรียกหางที่ทำเครื่องหมายไว้อย่างชัดเจน
soegaard

การเรียกหางที่ทำเครื่องหมายไว้อย่างชัดเจนอาจทำให้ทุกคนพอใจ
JD

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

8

forห่วงเป็นอย่างไร? ทำซ้ำหลาย ๆ ครั้งตามที่คุณต้องการ หรือwhileวนซ้ำทำซ้ำจนกว่าจะตรงตามเงื่อนไข มีโครงสร้างการควบคุมที่จะช่วยให้คุณทำรหัสซ้ำได้ ฉันจำได้ว่าGOTOใน Basic ... มันสร้างรหัสที่ไม่ดี! ภาษาโปรแกรมสมัยใหม่ให้ตัวเลือกที่ดีกว่าที่คุณสามารถดูแลรักษาได้จริง


วงจรการผลิตที่ไม่มีที่สิ้นสุด: ต้นแบบรอยขีดข่วนต้นแบบที่ดีกว่ารอยขีดข่วนต้นแบบที่ดีกว่ารอยขีดข่วน การบำรุงรักษามักจะผิดพลาด ไม่จำเป็นต้องรักษารหัสมากนัก โค้ดส่วนใหญ่เขียนใหม่ไม่ได้รับการดูแล
Pacerier

7

มีวิธีนี้ที่สามารถทำได้ แต่ต้องมีการวางแผนอย่างรอบคอบ ยกตัวอย่างเช่นโปรแกรม 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 ของคุณเพื่อเริ่มต้นตัวแปรทั้งหมดก่อนตามด้วยการเรียกใช้ฟังก์ชันเริ่มต้นเพื่อเริ่มการกลิ้งลูกบอล (เราเรียกใช้ฟังก์ชันเริ่มต้นนี้ในตอนท้าย) และตั้งค่าฟังก์ชันสำหรับทุกชุดของบรรทัดที่คุณทราบว่าจะดำเนินการใน หนึ่งหน่วย

ทำตามสิ่งนี้ด้วยการเรียกใช้ฟังก์ชันเริ่มต้น ...

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.

@JonHarrop มีขนาดสแต็กสูงสุดที่ JavaScript สามารถจัดการได้ก่อนที่สแต็กจะล้นหรือไม่?
Eliseo d'Annunzio

1
ใช่และดูเหมือนว่าจะเล็กมาก เล็กกว่าภาษาอื่น ๆ ที่ฉันเคยใช้
JD

7

โดยทั่วไปฉันไม่ต้องการใช้ GoTo สำหรับการอ่านที่ไม่ดี สำหรับฉันแล้วมันเป็นข้ออ้างที่ไม่ดีสำหรับการเขียนโปรแกรมฟังก์ชันวนซ้ำอย่างง่ายแทนที่จะต้องตั้งโปรแกรมฟังก์ชันแบบวนซ้ำหรือดีกว่านั้น (หากกลัวว่าจะมีสิ่งต่างๆเช่น Stack Overflow) ทางเลือกในการทำซ้ำที่แท้จริง (ซึ่งบางครั้งอาจซับซ้อน)

สิ่งนี้จะทำ:

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

นั่นคือการวนซ้ำที่ไม่มีที่สิ้นสุด นิพจน์ ("true") ภายใน parantheses ของ while clause คือสิ่งที่เอ็นจิ้น Javascript จะตรวจสอบ - และหากนิพจน์เป็นจริงก็จะทำให้ลูปทำงานต่อไป การเขียน "จริง" ที่นี่จะประเมินค่าเป็นจริงเสมอดังนั้นจึงวนซ้ำไม่สิ้นสุด


7

แน่นอนโดยใช้switchโครงสร้างที่คุณสามารถจำลองgotoใน JavaScript น่าเสียดายที่ภาษานี้ไม่มีให้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
  }
}

5

คุณอาจจะอ่านบทเรียน JS เช่นนี้อย่างใดอย่างหนึ่ง

ไม่แน่ใจว่าgotoมีอยู่ใน JS หรือไม่ แต่ไม่ว่าจะด้วยวิธีใดก็ตามจะส่งเสริมรูปแบบการเข้ารหัสที่ไม่ดีและควรหลีกเลี่ยง

คุณสามารถทำได้:

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

4

คุณสามารถใช้ฟังก์ชันง่ายๆ:

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

5
นี่เป็นความคิดที่แย่มากเพราะมันจะดันที่อยู่สำหรับส่งคืนใน call stack ไปเรื่อย ๆ จนกว่าหน่วยความจำจะหมด
Paul Hutchinson

1
อย่างไรก็ตามผู้ใช้จะมี CTRL-ALT-DELETEd ก่อนหน้านี้จากบทสนทนา RINSE-LATHER แบบไม่มีที่สิ้นสุด!
Shayne

4

เพื่อให้ได้ฟังก์ชันที่เหมือน goto ในขณะที่ทำให้ call stack สะอาดฉันใช้วิธีนี้:

// 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)ในเบราว์เซอร์รุ่นเก่า

AFAIK คุณไม่ควรเจอกรณีที่ต้องใช้วิธีนี้เว้นแต่คุณจะต้องหยุดการวนซ้ำที่ไม่ขนานกันชั่วคราวในสภาพแวดล้อมที่ไม่มีการรองรับ async / await


1
น่ารังเกียจ ฉันรักมัน. FWIW เทคนิคนี้เรียกว่า trampolining
JD

ฉันสามารถตรวจสอบว่าได้ผล ฉันถ่ายทอด HP RPN บางส่วนด้วยตัวเองด้วยคำสั่ง GTO ซึ่งนำไปสู่การเรียกซ้ำอย่างละเอียดเมื่อใช้งานเป็นการเรียกใช้ฟังก์ชัน เมธอด setTimeout () ที่แสดงด้านบนจะยุบสแต็กและการเรียกซ้ำไม่ใช่ปัญหาอีกต่อไป แต่จะช้ากว่ามาก โอ้ฉันกำลังทำสิ่งนี้ใน Node.js
Jeff Lowery

3

ไปเริ่มต้นและสิ้นสุดของการปิดพ่อแม่ทั้งหมด

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

3
// 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);
            }
        }

2

อีกทางเลือกหนึ่งในการบรรลุเป้าหมายเดียวกันคือการใช้การโทรหาง แต่เราไม่มีอะไรแบบนั้นใน JavaScript โดยทั่วไปแล้ว goto สามารถทำได้ใน JS โดยใช้คำหลักสองคำด้านล่าง ทำลายและ ดำเนินการต่ออ้างอิง: Goto Statement ใน JavaScript

นี่คือตัวอย่าง:

var number = 0;
start_position: while(true) {
document.write("Anything you want to print");
number++;
if(number < 100) continue start_position;
break;
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.