답변:
물론! 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의 결정에 대해 논의합니다.
그리고이 모든 것이 농담이라는 것을 즉시 인식하지 못하는 사람들을 위해, 저를 용서하십시오. <— (보험).
goto
아마도 활용률이 낮을 것 같습니다. 아주 좋은 오류 처리 패턴을 만듭니다. 우리 switch
는 goto
이름을 제외하고는 아랫배 통증이없는를 사용합니다.
아니요 . ECMAScript에는 포함되지 않았습니다.
ECMAScript에는 goto 문이 없습니다.
goto
는 바보 같은 "기능"의 자바 스크립트 칵테일에 완벽하게 잘 맞을 것입니다 :)
goto
그러나 나중에 사용하기 위해 예약 된 키워드입니다. 우리는 희망 만 있습니다 :)
goto
중첩 함수에서 돌아 오려고 할 때 유용합니다. 예를 들어 underscore.js를 사용하는 경우 배열을 반복 할 때 익명 함수를 제공합니다. 그런 함수 안에서 돌아올 수 없으므로 goto end;
유용합니다.
실제로 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. ...
}
}
break
있으며 루프에도 continue
사용될 수 있습니다 for
. 그러나 그들은 정말이야 하지 동등 goto
비교가, 관련 루프 (들)의 구조로 고정되어 주어진 goto
그것을 가지고 언어 - - 어느 곳으로 이동하는 물론 수 있습니다.
클래식 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 대신 루프를 사용할 수 있습니다.
continue
A의 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에서는 적절한 테일 호출을 지원하는 구현에서 가능합니다. 적절한 테일 호출을 지원하는 구현에서는 무제한의 활성 테일 호출을 가질 수 있습니다 (즉, 테일 호출은 "스택을 늘리지 않습니다").
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
루프, 조건이 충족 될 때까지 반복하십시오. 코드를 반복 할 수있는 제어 구조가 있습니다. 나는 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를 작성하여 모든 변수를 먼저 초기화 한 다음 볼 롤링을 시작하기 위해 초기 함수 호출을 수행하고 (이 초기 함수 호출을 마지막에 실행) 실행되는 모든 행 세트에 대해 함수를 설정하십시오. 한 단위.
초기 함수 호출로 이것을 따르십시오 ...
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 절의 paranthese에있는 표현식 ( "true")은 Javascript 엔진이 확인하는 것입니다. 표현식이 true이면 루프가 계속 실행됩니다. 여기에 "true"라고 쓰면 항상 true로 평가되므로 무한 루프입니다.
함수를 간단하게 사용할 수 있습니다.
function hello() {
alert("RINSE");
alert("LATHER");
hello();
}
콜 스택을 깨끗하게 유지하면서 고토와 같은 기능을 달성하기 위해이 방법을 사용하고 있습니다.
// 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, 비동기 / 대기 지원이없는 환경에서 병렬화 할 수없는 루프를 일시 중지해야하지 않는 한이 방법이 필요한 경우가 발생하지 않아야합니다.
// 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에서 수행됩니다. break and continue , 참조 : JavaScript의 Goto 문
예를 들면 다음과 같습니다.
var number = 0;
start_position: while(true) {
document.write("Anything you want to print");
number++;
if(number < 100) continue start_position;
break;
}