[javascript] Javascript에서 goto를 어떻게 사용합니까?

을 사용하여 구현 해야하는 코드가 goto있습니다. 예를 들어 다음과 같은 프로그램을 작성하고 싶습니다.

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

자바 스크립트로 그렇게 할 수 있습니까?



답변

물론! 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;

goto 구현 방법에 대한 자세한 내용을 읽을 수 있지만 기본적으로 레이블이 지정된 while루프 로 goto를 시뮬레이션 할 수 있다는 사실을 활용하는 JavaScript 전처리를 수행 합니다 . “Hello, world!”라고 쓸 때 위의 프로그램에서 다음과 같이 번역됩니다.

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

while 루프는 여러 기능이나 블록에 걸쳐 확장 될 수 없기 때문에이 전처리 프로세스에는 몇 가지 제한 사항이 있습니다. 그럼에도 불구하고 큰 문제 goto는 아닙니다. JavaScript를 활용할 수있는 이점이 당신을 압도 할 것입니다.

goto.js 라이브러리로 연결되는 위의 모든 링크는 ALL DEAD입니다. 필요한 링크는 다음과 같습니다.

goto.js (비 압축)parseScripts.js (비 압축)

에서 Goto.js :

추신 : 궁금한 사람 (지금까지 총 0 명)을 위해, Goto의 Summer는 Paul Irish가 대중화 한 용어이며,이 스크립트와 자신의 언어에 goto를 추가하려는 PHP의 결정에 대해 논의합니다.

그리고이 모든 것이 농담이라는 것을 즉시 인식하지 못하는 사람들을 위해, 저를 용서하십시오. <— (보험).


답변

아니요 . ECMAScript에는 포함되지 않았습니다.

ECMAScript에는 goto 문이 없습니다.


답변

실제로 ECMAScript (JavaScript)에 실제로는 문이 있습니다. 그러나 JavaScript goto에는 두 가지 맛이 있습니다!

goto의 두 가지 JavaScript 맛을 continue라고 표시하고 break라고 표시합니다. JavaScript에는 키워드 “goto”가 없습니다. goto는 break 및 continue 키워드를 사용하여 JavaScript로 수행됩니다.

그리고 이것은 w3schools 웹 사이트 http://www.w3schools.com/js/js_switch.asp 에 다소 명시 적으로 언급되어 있습니다 .

레이블이 붙은 계속 문서와 레이블 구분이 다소 어색하게 표현 된 것을 발견했습니다.

레이블 된 continue와 레이블 된 break의 차이점은 사용할 수있는 위치입니다. 레이블이있는 continue는 while 루프 내에서만 사용할 수 있습니다. 자세한 내용은 w3schools를 참조하십시오.

===========

작동하는 또 다른 접근법은 내부에 거대한 스위치 문이있는 거대한 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. ...
    }

}


답변

클래식 JavaScript에서는 이러한 유형의 코드를 달성하기 위해 do-while 루프를 사용해야합니다. 다른 코드를 생성하고 있다고 가정합니다.

바이트 코드를 JavaScript로 백엔드하는 것과 같이 수행하는 방법은 모든 레이블 대상을 “레이블이있는”작업으로 래핑하는 것입니다.

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

코드가 바이트 코드로 인코딩되었다고 가정하면 이제 바이트 코드를 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 대신 루프를 사용할 수 있습니다.


답변

이것은 오래된 질문이지만 JavaScript는 움직이는 목표이기 때문에 ES6에서는 적절한 테일 호출을 지원하는 구현에서 가능합니다. 적절한 테일 호출을 지원하는 구현에서는 무제한의 활성 테일 호출을 가질 수 있습니다 (즉, 테일 호출은 “스택을 늘리지 않습니다”).

A 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 다음에 오므로 D 뒤에 A를 추가합니다 goto label3.

 Block1
     label1:   A
               B
               if C goto label2
               D
               goto label2

  Block2
     label2:   E
               goto label1

이제 각 블록은 함수가되고 각 블록은 테일 호출이됩니다.

 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루프, 조건이 충족 될 때까지 반복하십시오. 코드를 반복 할 수있는 제어 구조가 있습니다. 나는 GOTOBasic에서 기억합니다 … 그런 나쁜 코드를 만들었습니다! 최신 프로그래밍 언어는 실제로 유지 관리 할 수있는 더 나은 옵션을 제공합니다.