Программы JavaScript состоят из операторов и объявлений функций. Когда выполняется программа JavaScript, выполняются следующие два шага:
-
код сканируется на наличие объявлений функций и всех функций. объявление "выполняется" (путем создания объекта функции) и создается именованная ссылка на эту функцию (так что эта функция может быть вызвана из оператора)
-
операторы выполняются (оцениваются) последовательно (как они появляются в коде)
Из-за этого это работает просто отлично:
<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 (в пределах одной веб-страницы) "используют" один и тот же глобальный объект, и все изменения, сделанные в глобальном объекте одной программой 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.
Пожалуйста, проверьте этот пост и скажите, если я что-то не так понял.
Кроме того, я не нашел ресурсов, объясняющих поведение, упомянутое в этом посте, и я предполагаю, что производители браузеров, должно быть, где-то публиковали такие ресурсы, поэтому, если вы знаете о них, пожалуйста, предоставьте ссылки на них.