Kesinlikle kullanmam gereken bazı kodlar var goto
. Örneğin şöyle bir program yazmak istiyorum:
start:
alert("RINSE");
alert("LATHER");
repeat: goto start
Bunu Javascript'te yapmanın bir yolu var mı?
Kesinlikle kullanmam gereken bazı kodlar var goto
. Örneğin şöyle bir program yazmak istiyorum:
start:
alert("RINSE");
alert("LATHER");
repeat: goto start
Bunu Javascript'te yapmanın bir yolu var mı?
Yanıtlar:
Kesinlikle! JavaScript'i tam potansiyelinde kullanmanıza izin veren ve kodunuzu yazma şeklinizde devrim yaratacak Summer of Goto adlı bir proje var .
Bu JavaScript ön işleme aracı, bir etiket oluşturmanıza ve ardından bu sözdizimini kullanarak ona gitmenize olanak tanır:
[lbl] <label-name>
goto <label-name>
Örneğin sorudaki örnek şu şekilde yazılabilir:
[lbl] start:
alert("LATHER");
alert("RINSE");
[lbl] repeat: goto start;
Sonsuz bir LATHER
RINSE
tekrar döngüsü gibi basit önemsiz programlarla sınırlı olmadığınızı unutmayın - sağladığı olanaklar goto
sonsuzdur ve hatta Hello, world!
şu şekilde JavaScript konsoluna 538 kez mesaj gönderebilirsiniz:
var i = 0;
[lbl] start:
console.log("Hello, world!");
i++;
if(i < 538) goto start;
Goto'nun nasıl uygulandığı hakkında daha fazla bilgi edinebilirsiniz , ancak temelde, etiketli bir while
döngü ile bir goto simülasyonu yapabileceğiniz gerçeğinden yararlanan bazı JavaScript ön işlemleri yapar . Öyleyse, "Merhaba dünya!" yukarıdaki program, aşağıdaki gibi bir şeye çevrilir:
var i = 0;
start: while(true) {
console.log("Hello, world!");
i++;
if(i < 538) continue start;
break;
}
Bu ön işleme sürecinde bazı sınırlamalar vardır, çünkü while döngüleri birden fazla işlev veya bloğa yayılamaz. Yine de bu önemli bir şey değil goto
- JavaScript'ten yararlanmanın faydalarının sizi kesinlikle bunaltacağına eminim.
Goto.js kitaplığına götüren yukarıdaki bağlantıların tümü TAMAMEN ÖLÜ, işte gerekli bağlantılar:
goto.js (sıkıştırılmamış) --- parseScripts.js (sıkıştırılmamış)
Gönderen Goto.js :
Not: Merak eden herkes için (şimdiye kadar toplam sıfır kişi), Summer of Goto, bu senaryoyu ve PHP'nin dillerine goto ekleme kararını tartışırken Paul Irish tarafından popüler hale getirilen bir terimdir.
Ve tüm bu şeyin bir şaka olduğunu hemen anlamayanlar için lütfen beni affet. <- (sigorta).
goto
muhtemelen yetersiz kullanıldığını düşünüyorum . Bazı çok güzel hata işleme kalıpları sağlar. Heck, biz switch
, goto
adı dışında her şeyi kullanıyoruz ve kimse karın ağrısı çekmiyor.
Hayır. Bunu ECMAScript'e dahil etmediler:
ECMAScript'in goto ifadesi yok.
goto
, javascript'in aptal "özelliklerinden" oluşan kokteyline mükemmel bir şekilde uyuyor :)
goto
ancak, ileride kullanılmak üzere ayrılmış bir anahtar kelimedir. Sadece umut edebiliriz :)
goto
iç içe geçmiş bir işlevden dönmek istediğinizde yararlı olacaktır. Örneğin, alt çizgi.js kullanırken, diziler üzerinde yineleme yaparken anonim bir işlev sağlarsınız. Böyle bir fonksiyonun içinden dönemezsiniz, bu yüzden goto end;
faydalı olacaktır.
Aslında, ECMAScript (JavaScript) DOES INDEED'in bir goto ifadesi olduğunu görüyorum. Ancak, JavaScript goto'nun iki çeşidi vardır!
Goto'nun iki JavaScript çeşidi, etiketli devam ve ara etiketli olarak adlandırılır. JavaScript'te "goto" anahtar kelimesi yoktur. Goto, JavaScript'te break ve continue anahtar sözcükleri kullanılarak gerçekleştirilir.
Ve bu, http://www.w3schools.com/js/js_switch.asp buradaki w3schools web sitesinde aşağı yukarı açıkça belirtilmiştir .
Devam et etiketli ve ara etiketli belgelerin biraz garip bir şekilde ifade edildiğini görüyorum.
Etiketli devam ve etiketli ara arasındaki fark, kullanılabilecekleri yerdir. Etiketli devam, yalnızca bir süre döngüsü içinde kullanılabilir. Daha fazla bilgi için w3schools'a bakın.
===========
İşe yarayacak başka bir yaklaşım, içinde dev bir anahtar ifadesi bulunan dev bir while ifadesine sahip olmaktır:
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
ve döngülerde de continue
kullanılabilir for
. Ama gerçekten konum değil eşdeğer goto
kıyasla bunlar, ilgili döngü (ler) in yapısına kilitlenmiş göz önüne alındığında goto
o var dilde - - her yerde gidip hangi elbette olabilir.
Klasik JavaScript'te, bu tür bir kodu elde etmek için do-while döngüleri kullanmanız gerekir. Sanırım başka bir şey için kod üretiyorsunuz.
Bayt kodunu JavaScript'e arka plana göndermek gibi bunu yapmanın yolu, her etiket hedefini "etiketli" bir işle kaplamaktır.
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);
Bu şekilde kullandığınız her etiketli do-while döngüsü aslında bir etiket için iki etiket noktası oluşturur. Biri en üstte ve diğeri döngünün sonunda. Geri atlamak devam eder ve ileri atlamak mola verir.
// 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)
Maalesef bunu yapmanın başka yolu yok.
Normal Örnek Kod:
while (x < 10 && Ok) {
z = 0;
while (z < 10) {
if (!DoStuff()) {
Ok = FALSE;
break;
}
z++;
}
x++;
}
Diyelim ki kod bayt kodlarına kodlandı, bu yüzden şimdi arka ucunuzu bir amaç için simüle etmek için bayt kodlarını JavaScript'e koymalısınız.
JavaScript stili:
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)
Dolayısıyla, bu tekniği kullanmak işi basit amaçlar için iyi yapar. Bunun dışında yapabileceğin pek bir şey yok.
Normal Javacript için hiçbir zaman goto kullanmanıza gerek yoktur, bu nedenle JavaScript üzerinde çalıştırmak için başka stil kodunu özel olarak çevirmediğiniz sürece muhtemelen bu teknikten kaçınmalısınız. Örneğin, Linux çekirdeğini JavaScript'te başlatmak için böyle yaptıklarını varsayıyorum.
NOT! Bu tamamen saf bir açıklama. Bayt kodlarının uygun Js arka ucu için, kodu çıktılamadan önce döngüleri incelemeyi de düşünün. Birçok basit while döngüsü bu şekilde algılanabilir ve daha sonra goto yerine döngüleri kullanmayı tercih edebilirsiniz.
continue
bir do ... while
döngüde kontrol koşuluna devam eder . goto
Burada geriye doğru kullanmak do ... while (0)
işe yaramaz. ecma-international.org/ecma-262/5.1/#sec-12.6.1
let doLoop
işe yaraması için yapmalıyım . Ve ana döngü: let doLoop = false; do { if(condition){ doLoop = true; continue; } } while (doLoop)
github.com/patarapolw/HanziLevelUp/blob/…
Bu eski bir sorudur, ancak JavaScript hareketli bir hedef olduğu için - doğru kuyruk çağrılarını destekleyen uygulamada ES6'da mümkündür. Uygun kuyruk çağrılarını destekleyen uygulamalarda, sınırsız sayıda aktif kuyruk çağrısına sahip olabilirsiniz (yani kuyruk çağrıları "yığını büyütmez").
A goto
, parametresi olmayan bir kuyruk çağrısı olarak düşünülebilir.
Örnek:
start: alert("RINSE");
alert("LATHER");
goto start
olarak yazılabilir
function start() { alert("RINSE");
alert("LATHER");
return start() }
Burada çağrı start
kuyruk konumunda olduğundan yığın taşması olmayacaktır.
İşte daha karmaşık bir örnek:
label1: A
B
if C goto label3
D
label3: E
goto label1
Önce kaynağı bloklara ayırdık. Her etiket yeni bir bloğun başlangıcını gösterir.
Block1
label1: A
B
if C goto label3
D
Block2
label3: E
goto label1
Gotos kullanarak blokları birbirine bağlamamız gerekiyor. Örnekte E bloğu D'yi takip eder, bu yüzden goto label3
D'den sonra bir ekleriz .
Block1
label1: A
B
if C goto label2
D
goto label2
Block2
label2: E
goto label1
Artık her blok bir işlev haline gelir ve her gitme bir kuyruk çağrısı olur.
function label1() {
A
B
if C then return( label2() )
D
return( label2() )
}
function label2() {
E
return( label1() )
}
Programı başlatmak için kullanın label1()
.
Yeniden yazma tamamen mekaniktir ve bu nedenle gerekirse sweet.js gibi bir makro sistemle yapılabilir.
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;
}
Bir for
döngü nasıl olur ? İstediğiniz kadar tekrarlayın. Veya bir while
döngü, bir koşul karşılanana kadar tekrarlayın. Kodu tekrarlamanıza izin verecek kontrol yapıları vardır. Temelde hatırlıyorum GOTO
... çok kötü bir kod yaptı! Modern programlama dilleri, gerçekten koruyabileceğiniz daha iyi seçenekler sunar.
Bunu yapmanın bir yolu var ama dikkatlice planlanması gerekiyor. Örneğin aşağıdaki QBASIC programını ele alalım:
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."
Ardından, önce tüm değişkenleri başlatmak için JavaScript'inizi oluşturun, ardından topun yuvarlanmasını başlatmak için bir ilk işlev çağrısı yapın (bu ilk işlev çağrısını sonunda yürütürüz) ve içinde çalıştırılacağını bildiğiniz her satır kümesi için işlevleri ayarlayın. tek birim.
Bunu ilk işlev çağrısıyla takip edin ...
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();
Bu durumda sonuç şudur:
a = 1
a = 2
a = 3
a = 4
a = 5
a = 6
a = 7
a = 8
a = 9
a = 10
That's the end.
Genel olarak, kötü okunabilirlik için GoTo'yu kullanmamayı tercih ederim. Bana göre bu, özyinelemeli işlevleri programlamak yerine basit yinelemeli işlevleri programlamak için kötü bir bahane veya daha da iyisi (Yığın Taşması gibi şeylerden korkuluyorsa), gerçek yinelemeli alternatifleri (bazen karmaşık olabilir).
Bunun gibi bir şey yapardı:
while(true) {
alert("RINSE");
alert("LATHER");
}
İşte sonsuz bir döngü var. While cümlesinin parantezleri içindeki ifade ("true"), Javascript motorunun kontrol edeceği şeydir - ve eğer ifade doğruysa, döngünün çalışmasını sağlar. Burada "doğru" yazmak her zaman doğru olarak değerlendirilir, dolayısıyla sonsuz bir döngüdür.
Elbette, switch
yapıyı kullanarak goto
JavaScript'te simüle edebilirsiniz . Maalesef dil sağlamıyor goto
, ancak bu yeterince iyi bir ikame.
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
}
}
Muhtemelen bu gibi bazı JS öğreticiler okumalı biri .
goto
JS'de var olup olmadığından emin değilim , ancak her iki durumda da kötü kodlama stilini teşvik eder ve bundan kaçınılmalıdır.
Yapabilirsin:
while ( some_condition ){
alert('RINSE');
alert('LATHER');
}
Bir işlevi basitçe kullanabilirsiniz:
function hello() {
alert("RINSE");
alert("LATHER");
hello();
}
Çağrı yığınını temiz tutarken goto benzeri işlevsellik elde etmek için şu yöntemi kullanıyorum:
// 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();
}
// ...
Lütfen, işlev çağrıları tarayıcının güncelleme döngüsünde daha sonra değerlendirilecek olan zaman aşımı kuyruğuna eklendiğinden bu kodun yavaş olduğunu unutmayın.
Lütfen bağımsız değişkenleri iletebileceğinizi de unutmayın ( setTimeout(func, 0, arg1, args...)
IE9'dan daha yeni tarayıcılarda veya setTimeout(function(){func(arg1, args...)}, 0)
eski tarayıcılarda kullanarak.
AFAIK, asenkron / bekleme desteği olmayan bir ortamda paralel olmayan bir döngüyü duraklatmanız gerekmedikçe, bu yöntemi gerektiren bir vakayla asla karşılaşmamalısınız.
tüm ebeveynlerin kapatmalarının başlangıcına ve sonuna git
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);
}
}
Aynı şeyi başarmanın bir başka alternatif yolu da kuyruk aramalarını kullanmaktır. Ancak JavaScript'te böyle bir şey yok. Genel olarak, goto, aşağıdaki iki anahtar kelime kullanılarak JS'de gerçekleştirilir. break ve Continue , başvuru: JavaScript'te Goto İfadesi
İşte bir örnek:
var number = 0;
start_position: while(true) {
document.write("Anything you want to print");
number++;
if(number < 100) continue start_position;
break;
}