2010-08-04 16 views
5

Mam trochę pracy z Javascriptem, który manipuluje niektórymi elementami DOM. Problem polega na tym, że nie rozumiem, dlaczego to działa, co nigdy nie jest dobre. Próbuję dowiedzieć się więcej na temat zorientowanych obiektowo javascript i najlepszych praktyk javascript, więc organizacja może wydawać się trochę dziwna.

Zasadniczo zawijam dwie metody, które manipulują DOM wewnątrz obiektu CSContent. Tworzę instancję tego obiektu, content w $(document).ready i wiążę niektóre zdarzenia z funkcjami w content. Nie jestem jednak pewien, w jaki sposób funkcje te można jeszcze wywoływać po wyjściu z trybu $(document).ready. Czy to nie oznacza, że ​​content wykracza poza zakres, a jego funkcje nie są dostępne? W każdym razie, oto kod:

+0

Czy możesz pokazać przykład miejsca, w którym masz dostęp do "treści", gdzie nie powinieneś mieć? –

+0

@Pekka: kiedy w elemencie o id 'edit-cscontent-cs-content-tweet' klawisz jest wciśnięty lub wciśnięty, na przykład? –

+0

@Marcel ahh, o to mu chodziło! To jest zamknięcie. Ale już wyjaśniasz, że w twojej odpowiedzi - dałbym +1, ale dzisiaj nie mam głosów. –

Odpowiedz

2

Zakładam, że zastanawiam się, dlaczego obsługi zdarzeń jak

$('#edit-cscontent-cs-content-twitter').change(content.toggleTweetTextarea); 

pracy?

Cóż, nie przechodzisz content jako funkcja obsługi zdarzeń, ale funkcja ta jest zawarta w content.toggleTweetTextarea. A to odniesienie będzie nadal istnieć po tym, jak content już nie istnieje. Nie ma w tym nic specjalnego. Właśnie przypisałeś obiekt (funkcję) do innej zmiennej. Dopóki istnieje co najmniej jedno odniesienie do obiektu, obiekt nie będzie zbierany śmieci.

Teraz możesz zapytać, dlaczego te funkcje mają nadal dostęp do np. tweetTextArea? To rzeczywiście jest zamknięcie. Gdy funkcje są tworzone za pomocą new CSContent(), kontekst aktywacji tej funkcji jest dodawany do łańcucha zasięgu wewnętrznych funkcji CSContent.toggleTweetTextarea i CSContent.updateTweetCharacterCount. Więc nawet jeśli nie masz już odniesienia do content, zakres tej funkcji jest nadal zawarty w łańcuchu zasięgu innych funkcji.

Po zakończeniu ready() nie będzie już można uzyskać dostępu do obiektu zawartego w content, a to faktycznie wykracza poza zakres.

5

To, panie, nazywany jest zamknięcie: lokalna zmienna content pozostanie w pamięci po $(document).ready wyjść. Jest to również znana przyczyna wycieków pamięci.

W skrócie, wiążesz tę funkcję z detektorem zdarzeń elementu DOM, a następnie moduł do zbierania śmieci JavaScript wie, że powinien on zachować zmienną lokalną w stanie nienaruszonym. Nie możesz wywołać go bezpośrednio (poza funkcją), chyba że zdarzenie zostanie wyzwolone. U niektórych można to zrobić "ręcznie", jeśli naprawdę chcesz wywołać funkcję później (np. Za pomocą element.click(), aby zasymulować kliknięcie).

+0

Ale poza tym są świetne! :) Dodatkowe czytanie: https: //developer.mozilla.org/pl/JavaScript/Guide/Closures –

+0

Czy można uzyskać dostęp do zmiennych lokalnych zadeklarowanych w konstruktorze CSContent, ponieważ jest to zamknięcie i nie wykracza poza zakres, ponieważ jest powiązany z detektorem zdarzeń? Czy też całe zamknięcie zostanie jakoś skopiowane do słuchacza? – jergason

+0

@Jergason: pierwszy. –

1

Mój mózg jest dziś wyłączony, ale czy nie powinno się używać zamknięć w tej sytuacji?

$('#edit-cscontent-cs-content-twitter').change( 
    function(){ 
     content.toggleTweetTextarea(); 
    } 
); 
+0

Dzisiaj ....? :) Hey Eric czy kiedykolwiek widziałeś ten komentarz: http://stackoverflow.com/questions/3274044/best-book-on-ajax/3306936#3306936 –

+0

Hmm, dobry pomysł, zamknięcia. Ale OP już używa jednego ...: P –

Powiązane problemy