2010-09-17 8 views
66

Programy JavaScript składają się z instrukcji i deklaracji funkcji. Po uruchomieniu programu JavaScript następujące dwa kroki:Ile programów JavaScript jest uruchamianych dla pojedynczej strony internetowej w przeglądarce?

  1. kod jest skanowany pod kątem deklaracji funkcji i każdego func. deklaracja jest "wykonywana" (przez utworzenie obiektu funkcji) i tworzone jest nazwane odniesienie do tej funkcji (aby funkcja ta mogła być wywoływana z poziomu instrukcji)

  2. instrukcje są wykonywane (oceniane) sekwencyjnie (tak jak pojawiają się w kodzie)

z tego powodu, to działa dobrze:

<script> 
    foo(); 
    function foo() { 
     return; 
    } 
</script> 

Chociaż funkcja „foo” nazywa zanim zostanie ogłoszony, to działa, bo zabawy Deklaracja ction jest oceniana przed oświadczeniem.

Jednak ta nie działa:

<script> 
    foo(); 
</script> 
<script> 
    function foo() { 
     return; 
    } 
</script> 

ReferenceError zostanie wyrzucony ("foo nie jest zdefiniowana"). Prowadzi to do wniosku, że każdy element SCRIPT w kodzie HTML strony reprezentuje odrębny program JavaScript i za każdym razem, gdy analizator składni HTML napotka element SCRIPT, wykonuje program wewnątrz tego elementu (a następnie po uruchomieniu programu , parser przechodzi do kodu HTML następującego po elemencie SCRIPT).

Potem znowu, to działa:

<script> 
    function foo() { 
     return; 
    } 
</script> 
<script> 
    foo(); 
</script> 

moim rozumieniu jest to, że istnieje globalnego obiektu (który służy jako zmienna obiektu w kontekście globalnym wykonania) (i pozostaje) w każdym czasie, więc pierwszy program JavaScript utworzy obiekt funkcji i sporządzi dla niego odniesienie, a następnie drugi program JavaScript użyje tego odnośnika do wywołania funkcji. Dlatego wszystkie programy JavaScript (w obrębie jednej strony internetowej) "wykorzystują" ten sam obiekt globalny, a wszystkie zmiany dokonane w obiekcie globalnym przez jeden program JavaScript mogą być obserwowane przez wszystkie uruchomione później programy JavaScript.

Teraz należy pamiętać, to ...

<script> 
    // assuming that foo is not defined 
    foo(); 
    alert(1); 
</script> 

W powyższym przypadku nadejścia połączenia nie wykona, ponieważ "foo()" oświadczenie rzuca ReferenceError (który rozkłada cały program JavaScript) i dlatego wszystkie kolejne instrukcje nie są wykonywane.

Jednak w tym przypadku ...

<script> 
    // assuming that foo is not defined 
    foo(); 
</script> 
<script> 
    alert(1); 
</script> 

Teraz nadejścia połączenia nie zostanie wykonany. Pierwszy program JavaScript rzuca odwołanie ReferenceError (aw konsekwencji przerwy), ale drugi program JavaScript działa normalnie. Oczywiście przeglądarka zgłosi błąd (chociaż wykonał kolejne programy JavaScript po wystąpieniu błędu).

Teraz, moje wnioski są następujące:

  • każdy element SCRIPT w kodzie HTML strony internetowej stanowi odrębny program JavaScript. Programy te są wykonywane natychmiast, gdy analizator składni HTML je napotka.
  • Wszystkie programy JavaScript na tej samej stronie internetowej "używają" tego samego obiektu globalnego. Ten obiekt globalny istnieje przez cały czas (od momentu pobrania strony internetowej do zniszczenia strony internetowej). Programy JavaScript mogą manipulować obiektem globalnym, a wszystkie zmiany dokonane w obiekcie globalnym za pomocą jednego programu JavaScript mogą być obserwowane we wszystkich kolejnych programach JavaScript.
  • jeśli jeden program JavaScript zepsuje się (przez zgłoszenie błędu), to nie przeszkadza w uruchomieniu kolejnych programów JavaScript.

Proszę sprawdzić fakturę i powiedzieć, czy coś jest nie tak.

Ponadto, nie znalazłem zasobów, które wyjaśniają zachowania wspomniane w tym poście, i zakładam, że twórcy przeglądarek musieli gdzieś opublikować takie zasoby, więc jeśli wiesz o nich, podaj linki do nich.

AKTUALIZACJA!

OK, idę do (spróbować) odpowiedzieć na moje własne pytanie tutaj :) Dostałem odpowiedź (poprzez e-mail) z Dmitry A. Soshnikov (prowadzi bloga o JavaScript w http://www.dmitrysoshnikov.com/).

Jego zdanie na ten temat brzmi następująco: każdy blok SCRIPT zawiera kod globalny. Wykonywanie każdego bloku SCRIPT tworzy nowy kontekst wykonania. Dlatego każdy blok SCRIPT ma swój własny kontekst wykonania, ale wszystkie te konteksty wykonania współużytkują ten sam obiekt globalny.

Bloki SCRIPT mogą być wyświetlane jako różne "podprogramy" o tym samym udostępnionym stanie.

Co więcej, specyfikacja ECMAScript (wydanie trzecie) stwierdza (rozdział 10): "Kod globalny to tekst źródłowy traktowany jako program ECMAScript."

Odpowiedz

14

Dmitry Soshnikov odpowiedział na Twoje pytanie. Każdy element <script> jest wykonywany jako Program, zgodnie z definicją ECMAScript. Istnieje jeden obiekt globalny, z którego korzysta każdy Program na pojedynczej stronie. I to naprawdę to.

7

Są to osobne programy, ale modyfikują udostępniony obiekt globalny.

19

Podnoszenie funkcji - proces, który ocenia oświadczenia function przed resztą funkcji - jest częścią standardu IIRC standardu ECMAScript (nie mogę teraz znaleźć odwołania, ale pamiętam, że widziałem dyskusje na temat EMCAScript, które go wymieniają). Ocena tagów script jest częścią standardu HTML. Nie określa, że ​​są one "oddzielnymi programami" w tak wielu słowach, ale mówi się, że elementy skryptu są oceniane w kolejności, w jakiej pojawiają się w dokumencie. Dlatego funkcje w późniejszych znacznikach skryptu nie są podnoszone: Skrypt nie został jeszcze oceniony. To również wyjaśnia, dlaczego zatrzymanie jednego skryptu nie odcina kolejnych skryptów: Kiedy bieżący skrypt przestaje oceniać, rozpoczyna się następny.

+0

Opis połączenia WYKAZ. http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting – Rajat

4

Innym sposobem myślenia o tym jest zasięg pseudo lokalny a globalny. Każda deklaracja SCRIPT ma zakres lokalny do jej obecnych metod/funkcji, a także dostęp do bieżącego (zadeklarowanego wcześniej) zakresu globalnego.Ilekroć w bloku SCRIPT zdefiniowana jest metoda/funkcja, zostaje ona dodana do globalnego zasięgu i staje się dostępna po blokach SCRIPT.

Również tutaj jest dalsze odniesienia z W3C deklaracji skrypt/Podnośniki/modyfikacji:

Dynamiczna modyfikacja dokumentu mogą być modelowane w następujący sposób:

  1. Wszystkie elementy SCRIPT są oceniane w kolejności, w której ładowany jest dokument.
  2. Wszystkie konstrukcje skryptów w obrębie danego elementu SCRIPT, które generują SGML CDATA są oceniane. Ich łączny wygenerowany tekst wstawiono w dokumencie zamiast elementu SCRIPT .
  3. Wygenerowana CDATA jest ponownie obliczana.

This jest kolejnym dobrym źródłem informacji na skrypt/funkcja oceny/deklaracji.

Powiązane problemy