Saya memiliki beberapa kode yang harus saya terapkan untuk digunakan goto
. Misalnya, saya ingin menulis program seperti ini:
start:
alert("RINSE");
alert("LATHER");
repeat: goto start
Apakah ada cara untuk melakukannya di Javascript?
Saya memiliki beberapa kode yang harus saya terapkan untuk digunakan goto
. Misalnya, saya ingin menulis program seperti ini:
start:
alert("RINSE");
alert("LATHER");
repeat: goto start
Apakah ada cara untuk melakukannya di Javascript?
Jawaban:
Benar! Ada sebuah proyek bernama Summer of Goto yang memungkinkan Anda menggunakan JavaScript pada potensi penuhnya dan akan merevolusi cara Anda dapat menulis kode Anda.
Alat preprocessing JavaScript ini memungkinkan Anda membuat label dan kemudian menggunakannya menggunakan sintaks ini:
[lbl] <label-name>
goto <label-name>
Misalnya, contoh dalam pertanyaan dapat ditulis sebagai berikut:
[lbl] start:
alert("LATHER");
alert("RINSE");
[lbl] repeat: goto start;
Perhatikan bahwa Anda tidak hanya terbatas pada program sepele yang sederhana seperti LATHER
RINSE
siklus berulang tanpa akhir — kemungkinan yang diberikan goto
tidak terbatas dan Anda bahkan dapat membuat Hello, world!
pesan ke konsol JavaScript 538 kali, seperti ini:
var i = 0;
[lbl] start:
console.log("Hello, world!");
i++;
if(i < 538) goto start;
Anda dapat membaca lebih lanjut tentang bagaimana goto diimplementasikan , tetapi pada dasarnya, ia melakukan beberapa preprocessing JavaScript yang memanfaatkan fakta bahwa Anda dapat mensimulasikan goto dengan loop berlabelwhile
. Jadi, ketika Anda menulis "Halo, dunia!" program di atas, akan diterjemahkan ke sesuatu seperti ini:
var i = 0;
start: while(true) {
console.log("Hello, world!");
i++;
if(i < 538) continue start;
break;
}
Ada beberapa batasan untuk proses preprocessing ini, karena sementara loop tidak dapat membentang di beberapa fungsi atau blok. Tapi itu bukan masalah besar — saya yakin manfaat bisa memanfaatkan goto
JavaScript akan benar-benar membuat Anda kewalahan.
Semua tautan di atas yang mengarah ke pustaka goto.js adalah SEMUA MATI, di sini ada tautan yang dibutuhkan:
goto.js (tidak terkompresi) --- parseScripts.js (tidak terkompresi)
Dari Goto.js :
PS Bagi siapa saja yang bertanya-tanya (sejauh ini nol orang), Summer of Goto adalah istilah yang dipopulerkan oleh Paul Irish, saat membahas skrip ini dan keputusan PHP untuk menambahkan goto ke dalam bahasa mereka.
Dan bagi mereka yang tidak segera menyadari bahwa semua ini adalah lelucon, tolong maafkan saya. <- (asuransi).
goto
mungkin kurang dimanfaatkan. Itu membuat beberapa pola penanganan kesalahan yang sangat bagus. Heck, kita gunakan switch
, yang goto
semuanya kecuali nama, dan tidak ada yang sakit perut.
Tidak. Mereka tidak memasukkannya ke dalam ECMAScript:
ECMAScript tidak memiliki pernyataan goto.
goto
akan cocok dengan koktail javascript dari "fitur" :) :)
goto
adalah kata kunci yang dipesan untuk penggunaan di masa mendatang. Kami hanya bisa berharap :)
goto
akan berguna saat Anda ingin kembali dari fungsi bersarang. Misalnya, saat menggunakan underscore.js, Anda memberikan fungsi anonim saat iterating over array. Anda tidak dapat kembali dari dalam fungsi seperti itu, jadi goto end;
akan berguna
Sebenarnya, saya melihat bahwa ECMAScript (JavaScript) TIDAK MENGGUNAKAN pernyataan goto. Namun, goto JavaScript memiliki dua rasa!
Dua rasa JavaScript dari goto disebut berlabel lanjut dan berlabel istirahat. Tidak ada kata kunci "goto" di JavaScript. Goto diselesaikan dalam JavaScript menggunakan istirahat dan melanjutkan kata kunci.
Dan ini kurang lebih secara eksplisit dinyatakan di situs web w3schools di sini http://www.w3schools.com/js/js_switch.asp .
Saya menemukan dokumentasi dari label berlabel terus dan label agak canggung diekspresikan.
Perbedaan antara terus berlabel dan istirahat berlabel adalah di mana mereka dapat digunakan. Berlanjut berlabel hanya dapat digunakan di dalam loop sementara. Lihat sekolah w3 untuk informasi lebih lanjut.
===========
Pendekatan lain yang akan bekerja adalah memiliki pernyataan sementara raksasa dengan pernyataan beralih raksasa di dalamnya:
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
dan continue
dapat digunakan dalam for
loop juga. Tapi mereka benar-benar tidak setara dengan goto
mengingat bahwa mereka terkunci ke dalam struktur loop terkait, dibandingkan dengan goto
yang tentu saja - dalam bahasa yang memilikinya - pergi ke mana saja.
Dalam JavaScript klasik, Anda perlu menggunakan loop do-while untuk mencapai jenis kode ini. Saya kira Anda mungkin menghasilkan kode untuk beberapa hal lain.
Cara untuk melakukannya, seperti mem-backend bytecode ke JavaScript adalah dengan membungkus setiap target label dengan do-while "berlabel".
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);
Setiap loop do-while berlabel yang Anda gunakan seperti ini sebenarnya menciptakan dua titik label untuk satu label. Satu di bagian atas dan satu di ujung lingkaran. Melompat kembali menggunakan terus dan melompat maju menggunakan istirahat.
// 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)
Sayangnya tidak ada cara lain untuk melakukannya.
Kode Contoh Normal:
while (x < 10 && Ok) {
z = 0;
while (z < 10) {
if (!DoStuff()) {
Ok = FALSE;
break;
}
z++;
}
x++;
}
Jadi katakanlah kode akan dikodekan ke bytecodes jadi sekarang Anda harus memasukkan bytecode ke dalam JavaScript untuk mensimulasikan backend Anda untuk beberapa tujuan.
Gaya 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)
Jadi menggunakan teknik ini melakukan pekerjaan dengan baik untuk tujuan sederhana. Selain itu tidak banyak lagi yang bisa Anda lakukan.
Untuk Javacript biasa Anda tidak perlu menggunakan goto, jadi Anda mungkin harus menghindari teknik ini di sini kecuali jika Anda secara spesifik menerjemahkan kode gaya lain untuk dijalankan di JavaScript. Saya berasumsi itu adalah bagaimana mereka membuat kernel Linux untuk boot dalam JavaScript misalnya.
CATATAN! Ini semua penjelasan yang naif. Untuk backend Js yang tepat dari bytecodes juga pertimbangkan memeriksa loop sebelum mengeluarkan kode. Banyak loop sederhana sementara dapat dideteksi seperti itu dan kemudian Anda bisa menggunakan loop bukan goto.
continue
dalam satu do ... while
lingkaran berlanjut ke kondisi pemeriksaan . Mundur di goto
sini menggunakan do ... while (0)
demikian tidak bekerja. ecma-international.org/ecma-262/5.1/#sec-12.6.1
let doLoop
ini agar berhasil. Dan loop utama: let doLoop = false; do { if(condition){ doLoop = true; continue; } } while (doLoop)
github.com/patarapolw/HanziLevelUp/blob/…
Ini adalah pertanyaan lama, tetapi karena JavaScript adalah target yang bergerak - dimungkinkan dalam ES6 pada implementasi yang mendukung panggilan ekor yang tepat. Pada implementasi dengan dukungan untuk panggilan ekor yang tepat, Anda dapat memiliki jumlah panggilan ekor aktif yang tidak terbatas (mis. Panggilan ekor tidak "menumbuhkan tumpukan").
SEBUAH goto
dapat dianggap sebagai panggilan ekor tanpa parameter.
Contoh:
start: alert("RINSE");
alert("LATHER");
goto start
dapat ditulis sebagai
function start() { alert("RINSE");
alert("LATHER");
return start() }
Di sini panggilan untuk start
berada di posisi ekor, sehingga tidak akan ada tumpukan yang meluap.
Ini adalah contoh yang lebih kompleks:
label1: A
B
if C goto label3
D
label3: E
goto label1
Pertama, kami membagi sumber menjadi beberapa blok. Setiap label menunjukkan awal dari blok baru.
Block1
label1: A
B
if C goto label3
D
Block2
label3: E
goto label1
Kita perlu mengikat blok bersama-sama menggunakan gotos. Dalam contoh, blok E mengikuti D, jadi kami menambahkan goto label3
setelah D.
Block1
label1: A
B
if C goto label2
D
goto label2
Block2
label2: E
goto label1
Sekarang setiap blok menjadi fungsi dan setiap goto menjadi panggilan ekor.
function label1() {
A
B
if C then return( label2() )
D
return( label2() )
}
function label2() {
E
return( label1() )
}
Untuk memulai program, gunakan label1()
.
Penulisan ulang adalah murni mekanis dan dengan demikian dapat dilakukan dengan sistem makro seperti sweet.js jika perlu.
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;
}
Bagaimana dengan for
loop? Ulangi sebanyak yang Anda suka. Atau satu while
loop, ulangi sampai suatu kondisi terpenuhi. Ada struktur kontrol yang memungkinkan Anda mengulangi kode. Saya ingat GOTO
di Basic ... itu membuat kode yang buruk! Bahasa pemrograman modern memberi Anda pilihan yang lebih baik yang sebenarnya bisa Anda pertahankan.
Ada cara yang bisa dilakukan, tetapi perlu direncanakan dengan hati-hati. Ambil contoh program QBASIC berikut:
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."
Kemudian buat JavaScript Anda untuk menginisialisasi semua variabel terlebih dahulu, diikuti dengan membuat panggilan fungsi awal untuk memulai bola bergulir (kami menjalankan panggilan fungsi awal ini di akhir), dan mengatur fungsi untuk setiap rangkaian garis yang Anda tahu akan dieksekusi di satu unit.
Ikuti ini dengan panggilan fungsi awal ...
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();
Hasilnya dalam hal ini adalah:
a = 1
a = 2
a = 3
a = 4
a = 5
a = 6
a = 7
a = 8
a = 9
a = 10
That's the end.
Secara umum, saya lebih suka tidak menggunakan GoTo untuk keterbacaan yang buruk. Bagi saya, itu adalah alasan buruk untuk pemrograman fungsi iteratif sederhana daripada harus memprogram fungsi rekursif, atau bahkan lebih baik (jika hal-hal seperti Stack Overflow ditakuti), alternatif iteratif mereka yang sebenarnya (yang kadang-kadang mungkin rumit).
Sesuatu seperti ini akan dilakukan:
while(true) {
alert("RINSE");
alert("LATHER");
}
Itu benar ada loop tak terbatas. Ekspresi ("true") di dalam parantheses sementara sementara adalah apa yang akan diperiksa oleh mesin Javascript - dan jika ekspresi itu benar, itu akan membuat loop tetap berjalan. Menulis "benar" di sini selalu bernilai true, karenanya merupakan infinite loop.
Tentu, menggunakan switch
konstruk yang dapat Anda simulasikan goto
dalam JavaScript. Sayangnya, bahasa tidak menyediakan goto
, tetapi ini cukup baik sebagai pengganti.
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
}
}
Anda mungkin harus membaca beberapa tutorial JS seperti ini satu .
Tidak yakin apakah goto
ada di JS sama sekali, tetapi, bagaimanapun, itu mendorong gaya pengkodean yang buruk dan harus dihindari.
Anda bisa melakukannya:
while ( some_condition ){
alert('RINSE');
alert('LATHER');
}
Anda dapat menggunakan fungsi:
function hello() {
alert("RINSE");
alert("LATHER");
hello();
}
Untuk mencapai fungsionalitas seperti goto sambil menjaga tumpukan panggilan tetap bersih, saya menggunakan metode ini:
// 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();
}
// ...
Harap perhatikan bahwa kode ini lambat karena panggilan fungsi ditambahkan ke antrean batas waktu, yang kemudian dievaluasi, dalam loop pembaruan browser.
Harap perhatikan juga bahwa Anda dapat memberikan argumen (menggunakan setTimeout(func, 0, arg1, args...)
di browser yang lebih baru dari IE9, atau setTimeout(function(){func(arg1, args...)}, 0)
di browser yang lebih lama.
AFAIK, Anda seharusnya tidak pernah menemukan kasus yang memerlukan metode ini kecuali jika Anda perlu menjeda loop yang tidak dapat diparalelkan dalam lingkungan tanpa dukungan async / menunggu.
mulai dan berakhir dari semua penutupan orang tua
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);
// 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);
}
}
Cara alternatif lain untuk mencapai hal yang sama adalah dengan menggunakan panggilan ekor. Namun, kami tidak memiliki yang seperti itu di JavaScript. Jadi secara umum, goto diselesaikan di JS menggunakan dua kata kunci di bawah ini. istirahat dan lanjutkan , referensi: Pernyataan Goto dalam JavaScript
Berikut ini sebuah contoh:
var number = 0;
start_position: while(true) {
document.write("Anything you want to print");
number++;
if(number < 100) continue start_position;
break;
}