2012-12-12 13 views
5

Poniższy kod przedstawiono w książce Head First jQuery.Zmienna niezdefiniowana, czasami

function lightning_one(t) { 
$("#lightning1").fadeIn(250).fadeOut(250); 
setTimeout("lightning_one()", t); 
}; // end lightning_one 

Zostaje wywołany z tą linią.

lightning_one(3000); 

Obserwowane zachowanie się jest to, że piorun zanika i na raz, po 3 sekundach zanika i ponownie, a następnie nadal pojawiają się i na zewnątrz. Firebug nie wykazuje błędów javascript.

Rozumiem, dlaczego widzę to, co widzę. Myślałam, że będę próbować zachować drugi przedział 3, więc zmieniłem to:

setTimeout("lightning_one()", t); // nothing in the brackets 

do tego:

setTimeout("lightning_one(t)", t); // t is in the brackets 

Kiedy odśwież stronę, błyskawica zanika i obecnie raz. Firebug mówi mi, że zmienna t jest niezdefiniowana.

Moje pytanie brzmi, czy zmienna t nie jest zdefiniowana po mojej zmianie, w jaki sposób komenda działa bez błędu, zanim ją zmieniłem? Wciąż ma zmienną o nazwie t.

Więcej informacji

Dziękuję każdemu, kto pisał komentarze i odpowiedzi. Dla przypomnienia, w folderze „END”, kod staje się w ten sposób:

lightning_one(); 

    function lightning_one(){ 
$("#container #lightning1").fadeIn(250).fadeOut(250); 
setTimeout("lightning_one()",4000); 
    }; 

Nie skończyłem jeszcze obowiązujący rozdział, więc nie wiem, czy zmiana kodu pobiera zasugerował później. Jak wspomniano wcześniej, może to nie być najlepsza książka tam. Jednak to jest ten, który kupiłem i poznaję podstawy jQuery.

+4

Naprawdę przekazują ciąg do 'setTimeout'? Rzuć tę książkę daleko. – Bergi

+0

Myślałem o tym samym: Myślałem, że wywoływanie funkcji w ten sposób jest złą praktyką ... Nie jest to coś, czego powinno się uczyć w książce! – jahroy

+0

Widziałem wiele słów na ten temat, gdy próbowałem znaleźć odpowiedź na własną rękę. Wywołanie funkcji bez cudzysłowów było jednym z moich nieudanych prób. Jednak w moim pytaniu uważałem, że dokładny cytat będzie najlepszym sposobem. –

Odpowiedz

6

Ponieważ pierwszym argumentem w postaci ciągu jest eval -ed, co oznacza, że ​​zajrzy do zewnętrznego zakresu funkcji, w której t nie jest zdefiniowany. Pierwszy z nich jest w porządku, ponieważ nie używasz żadnych zmiennych w wywołaniu, ale drugi nie jest, ponieważ t nie jest zdefiniowany poza zakresem funkcji. Jest to w rzeczywistości lokalne.

Porada: Nie używaj w ogóle eval. W rzeczywistości nie potrzebujesz argumentu łańcuchowego. Użycie wyrażenia funkcyjne:

setTimeout(function() { 

    lightning_one(t); 

}, t); 
2

Ten będzie praca:

setTimeout(function() { lightning_one(t); }, t); 

jestem całkiem pewny, wywoływanie funkcji z ciągiem (i pozwalając mu się analizowany) jest złą praktyką, która powinna być unikany.

+0

Ta odpowiedź rzeczywiście działa. –

Powiązane problemy