Сколько программ JavaScript выполняется для одной веб-страницы в браузере? - PullRequest
67 голосов
/ 17 сентября 2010

JavaScript-программы состоят из операторов и объявлений функций. Когда выполняется программа JavaScript, выполняются следующие два шага:

  1. код проверяется на наличие объявлений функций и каждой функции. объявление «выполняется» (путем создания объекта функции) и создается именованная ссылка на эту функцию (чтобы эту функцию можно было вызывать из оператора)

  2. операторы выполняются (оцениваются) последовательно (как они появляются в коде)

Из-за этого работает просто отлично :

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

Хотя функция "foo" вызывается до ее объявления, она работает, потому что объявление функции вычисляется перед оператором.

Однако это не работает :

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

Будет сгенерировано ReferenceError («foo не определен»). Это приводит к выводу, что каждый элемент SCRIPT внутри HTML-кода веб-страницы представляет отдельную программу JavaScript, и каждый раз, когда анализатор HTML встречает элемент SCRIPT, он выполняет программу внутри этого элемента (а затем, как только программа выполняется, парсер переходит к HTML-коду, который следует за элементом SCRIPT).

Опять же, это работает :

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

Здесь я понимаю, что глобальный объект (который служит объектом переменной в глобальном контексте выполнения) существует (и остается) всегда, поэтому первая программа JavaScript создаст объект функции и создаст для него ссылку, а затем вторая программа JavaScript будет использовать эту ссылку для вызова функции. Поэтому все программы JavaScript (на одной веб-странице) «используют» один и тот же объект Global, и все изменения, сделанные в объекте Global одной программой JavaScript, могут наблюдаться всеми программами JavaScript, которые запускаются впоследствии.

Теперь, обратите внимание на это ...

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

В вышеприведенном случае вызов оповещения не будет выполнен , потому что оператор "foo ()" выбрасывает ReferenceError (который нарушает всю программу JavaScript) и, следовательно, все последующие операторы не выполняются.

Однако в этом случае ...

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

Теперь тревожный вызов выполняется . Первая JavaScript-программа генерирует ReferenceError (и, как следствие, прерывается), но вторая JavaScript-программа работает нормально. Конечно, браузер сообщит об ошибке (хотя он и выполнял последующие программы JavaScript после возникновения ошибки).

Теперь мои выводы:

  • каждый элемент SCRIPT в HTML-коде веб-страницы представляет собой отдельную программу JavaScript. Эти программы выполняются сразу же, как только синтаксический анализатор HTML сталкивается с ними.
  • все программы JavaScript на одной веб-странице "используют" один и тот же объект Global. Этот Глобальный объект существует постоянно (с момента загрузки веб-страницы до ее уничтожения). Программы JavaScript могут манипулировать объектом Global, и все изменения, внесенные в объект Global одной программой JavaScript, можно наблюдать во всех последующих программах JavaScript.
  • если одна из программ JavaScript выходит из строя (из-за ошибки), это не мешает выполнению последующих программ JavaScript.

Пожалуйста, проверьте этот пост и скажите, если я что-то не так понял.

Кроме того, я не нашел ресурсов, объясняющих поведение, упомянутое в этом посте, и я предполагаю, что производители браузеров, должно быть, где-то публиковали такие ресурсы, поэтому, если вы знаете о них, пожалуйста, предоставьте ссылки на них.

Ответы [ 4 ]

19 голосов
/ 17 сентября 2010

Подъем функции - процесс, который оценивает операторы function перед остальной частью функции - является частью стандарта IIRC ECMAScript (сейчас я не могу найти ссылку, но я вспоминаю, как я видел обсуждения EMCAScript, в которых он упоминается),Оценка тегов script является частью стандарта HTML.Он не указывает, что они являются «отдельными программами» во многих словах, но он говорит, что элементы сценария оцениваются в порядке, в котором они появляются в документе.Вот почему функции в более поздних тегах скрипта не поднимаются: скрипт еще не был оценен.Это также объясняет, почему остановка одного сценария не обрезает последующие сценарии: когда текущий сценарий останавливает оценку, запускается следующий.

15 голосов
/ 19 октября 2010

Дмитрий Сошников ответил на ваш вопрос.Каждый элемент <script> выполняется как Программа, как определено спецификацией ECMAScript.Существует один глобальный объект, который использует каждая Программа на одной странице.И это действительно так.

7 голосов
/ 17 сентября 2010

Это отдельные программы, но они изменяют общий глобальный объект.

4 голосов
/ 21 октября 2010

Еще один способ думать об этом - псевдо локальный или глобальный охват.Каждое объявление SCRIPT имеет локальную область видимости для своих текущих методов / функций, а также доступ к текущей (ранее объявленной) глобальной области видимости.Всякий раз, когда метод / функция определяется в блоке SCRIPT, он затем добавляется в глобальную область и становится доступным для блоков SCRIPT после него.

Кроме того, вот дополнительная ссылка из W3C при объявлении / обработке / изменении сценария:

Динамическое изменение документа может быть смоделировано следующим образом:

  1. Все элементы SCRIPT оцениваются по порядку при загрузке документа.
  2. Все скриптовые конструкции внутри данного элемента SCRIPT, которые генерируют SGML CDATA, оцениваются.Их объединенный сгенерированный текст вставляется в документ вместо элемента SCRIPT.
  3. Сгенерированный CDATA переоценивается.

Это еще один хороший ресурс по оценке сценария / функции / декларации.

...