A, {}

2012-06-13 17 views
5

olmadan bir döngü için bir dizi karıştırmayı okuyordum. Sonra this script rastladım: Ben yakından baktığınızdaA, {}

shuffle = function(o){ //v1.0 
    for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x); 
    return o; 
}; 

, for bile hiç bir {} yok! Ama sihir gibi çalışıyor. Nasıl çalıştığını bilmek çok merak ediyorum. tek satırda buysa (ve çok virgül demet.)

+0

Döngü için yalnızca bir tane varsa, komut dosyası çalışır, ancak birbiri ardına birden fazla haklarınız varsa, bu ifadeleri ayırmanız gerekir. – Rayshawn

cevap

10

; Bu, küme parantezli bir şey olabilir veya tek bir ifade olabilir veya boş bir ifade olabilir. for (...);, for (...) {} ile eşdeğerdir. Doğal olarak, bu sadece doğal olarak sona erecek olan bir döngü ile birlikte kullanılmalıdır ya da ellerinizde sonsuz bir döngü olacaktır.

Virgüller etkili ikinci dereceden noktalı virgüllerdir; Çoğunlukla ayrı ifadeler yaparlar, ancak bir döngü içinde çalışacaklardır (ve başka yerlerde; bu, onların çok özensiz bir tanımıdır).

for (
    // initialisation: declare three variables 
    var j, x, i = o.length; 
    // The loop check: when it gets to ``!i``, it will exit the loop 
    i; 
    // the increment clause, made of several "sub-statements" 
    j = parseInt(Math.random() * i), 
    x = o[--i], 
    o[i] = o[j], 
    o[j] = x 
) 
    ; // The body of the loop is an empty statement 

Bu şekilde daha okunabilir bir biçimde koymak mümkündür: while döngüsüne olarak

for (
    // initialisation: declare three variables 
    var j, x, i = o.length; 
    // The loop check: when it gets to ``!i``, it will exit the loop 
    i; 
    // note the increment clause is empty 
) { 
    j = parseInt(Math.random() * i); 
    x = o[--i]; 
    o[i] = o[j]; 
    o[j] = x; 
} 

, bu olabilir:

var j, x, i = o.length; 
while (i) { 
    j = parseInt(Math.random() * i); 
    x = o[--i]; 
    o[i] = o[j]; 
    o[j] = x; 
} 
+0

''a kadar,()' ise daha anlaşılabilir IMO'dur. –

+0

Gerçekten, bu şekilde daha anlaşılabilir. –

1

, hiçbir parantez gereklidir. Bu üçüncü bölümde parantez içinde bir çok kez, sadece i++ ya da bunun gibi bir şey görürsünüz. Gerçekten, orada birçok farklı şey yapabilirsin. Bu üçüncü bölümdeki her şeyi paketleyebiliyorsanız, for döngüsü için bir gövdeye bile ihtiyacınız yoktur.

for (first section; second section; third section); 

Değişkenler ilan ve başlatılır

İlk bölümü. Bu değişkenler, döngünün kapsamı içerisindedir.

İkinci bölüm

Bu döngünün her geçişte ile kontrol durumdur. Her peşinden koşar

Üçüncü bölüm

Kod döngü geçer. Bir değişkeni arttırmak kadar basit ve karmaşık bir şekilde ... ... sözdizimi doğru olduğu sürece, hatta sığabilecek herhangi bir şey.

+0

Aslında hiç satır yok. Döngü için hiç bir beden yok. – TheHippo

1

Döngüyü doğru okumadığım anlaşılıyor.

Bu durumda, değerlendirmeler for döngüsü koşullarında gerçekleşiyor.

Yani bir döngü için üç bölümden

for (initial variables; end cases; what to do every iteration) 

Bazı başlangıç ​​şeyler tanımlayabilir ve işlevi geçirildi o kullanmak, bir uç durumda tanımlamak ve sonra bir şey her yinelemesini hesaplamak vardır. Sonunda, o yeni bir değere sahip ve geri döndü.

+0

Hayır öyle değil. (bu örnekte) '' için '', 'for();'? –

+0

Üzgünüz, parantez yanlış. cevabımı güncelledi. – sachleen

4

Her hesaplama, {} 'ye değil, aynı zamanda bu ifadeye de gereksinim duyduğumuz tek bir ifade için aynı ifadedir; (cümlede sonlandırıcı kullanılır) bir sonraki ifadenin ifadeye ait olmadığı anlamına gelir. Mantık ne olursa olsun, deyim için aynıdır.

for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x); 


    for(var j, x, i = o.length;// Initialization 
    i;// Work until i is zero 
j = parseInt(Math.random() * i), 
    x = o[--i], o[i] = o[j], o[j] = x);//Here he is computing his logic 
0

Tüm çalışmalar aslında for beyanı Pars dahilinde yapılıyor. Döngü için açık bir beden yoktur, bu yüzden ; sonunda sadece vücudun boş bir ifade olduğunu söyler.

, (virgül) operatörü, ifadeleri soldan sağa doğru değerlendirir ve en sağdaki değeri döndürür.

döngü için temelde aynıdır: for() herhangi bir ifade olabilir aşağıdaki Ne

for(var j, x, i = o.length; i > 0;) 
{ 
    j = parseInt(Math.random() * i--); 
    x = o[i]; 
    o[i] = o[j]; 
    o[j] = x 
} 
+0

Neden 'i> 0;'? –

+0

javascript döngü koşulunu değerlendirdiğinde ('i'), sıfır olmayan herhangi bir değer için true değerini ve değer 0 olduğunda false değerini değerlendirir.' I> 0' derken sadece Aynı şeyi söylemenin daha açık bir yolu. Döngü, dizinin uzunluğundan 0. –

2

Birincisi, dikkat etmek istiyorum Böyle bir döngü kötü bir stil olarak kabul edilir, çünkü çok okunamaz ve çok fazla karışıklığa neden olur. Bu, optimizasyonun yanlış giden tipik bir örneğidir. specs baktığımızda

, sen for(...) bir açıklamada gelmelidir olduğunu göreceksiniz. Bloklar dahil olmak üzere any statement olabilir. Yani tüm bunlar geçerlidir: ";" beri

for (...) 
    foo; // expression statement 

,

for(...) 
    { 
     // block statement 
    } 

,

for(...) 
    if(...) // If statement 
     foo; 

ve tabii

for (...) 
    ; 

ait empty statement olduğunu. Hiçbir şey yapmaz, ancak for(...); sözdiziminde geçerli olması yeterlidir.

Şimdi, virgül için. Parentlerin içeriklerinin noktalı virgülle ayrılmış üç expressions (her biri isteğe bağlı) olması gerektiğini unutmayın. Oldukça "her şey" comma-separated lists of expressions dahil olmak üzere ifadeler olarak nitelendirilir. Az bilinen olsa da, bunlar temelde JS'de her yerde çalışır, sadece for döngülerinde değil. Sadece birbiri ardına değerlendirilirler.

Yani, döngü Ayrıca böylece

shuffle = function(o) { 
    var j, x, i = o.length; 
    while (i) { // for-loops are just while-loops in disguise 
     j = parseInt(Math.random() * i), // even better: replace , by ; 
     x = o[--i], 
     o[i] = o[j], 
     o[j] = x; 
    } 
    return o; 
}; 

gibi tekrar yazılabilir, x = o[--i]i--; x = o[i] olarak yazılmalıdır.

+0

'ifadesini takip etmelisiniz…' 'Gerçekten de, özelliklerde:' b. "Bildirim" değerlendirmesinin sonucu "stmt" olsun. c. Eğer stmt.value boş değilse, ... '' Birşeyler olup olmadığını kontrol etmeli, çünkü '' Deyim '' boş olabilir. –

+0

"Bir şey olup olmadığını kontrol etmiyor" - iyi, * İfadede * İfadeyi yazıyor, yani bir [cümle] olmalı (http://es5.github.com/#x12) "hiçbir şey değil". * Değeri * boş olabilir, örneğin 'dönüş 'ifadesini alır. – user123444555621

+0

Bu kafa karıştırıcı. Yani * hiçbir şey * * hiçbir şey * veya bir * EmptyStatement * olarak yorumlanır? –

İlgili konular