JavaScriptプログラムは、ステートメントと関数宣言で構成されています。JavaScriptプログラムを実行すると、次の2つの手順が実行されます。
コードは、関数宣言とすべての関数についてスキャンされます。宣言は(関数オブジェクトを作成することによって)「実行」され、その関数への名前付き参照が作成されます(この関数をステートメント内から呼び出すことができるように)
ステートメントは順番に実行(評価)されます(コードに表示されるとおり)
そのため、これは問題なく機能します:
<script>
foo();
function foo() {
return;
}
</script>
「foo」関数は宣言される前に呼び出されますが、関数宣言はステートメントの前に評価されるため、機能します。
ただし、これは機能しません:
<script>
foo();
</script>
<script>
function foo() {
return;
}
</script>
ReferenceErrorがスローされます(「fooが定義されていません」)。これにより、WebページのHTMLコード内のすべてのSCRIPT要素が個別のJavaScriptプログラムを表し、HTMLパーサーがSCRIPT要素に遭遇するたびに、その要素内のプログラムを実行する(そして、プログラムが実行されると、パーサーは、SCRIPT要素に続くHTMLコードに移動します)。
次に、これは機能します:
<script>
function foo() {
return;
}
</script>
<script>
foo();
</script>
ここでの私の理解は、グローバルオブジェクト(グローバル実行コンテキストで変数オブジェクトとして機能する)は常に存在する(そして残る)ので、最初のJavaScriptプログラムが関数オブジェクトを作成し、それを参照し、次に2番目のJavaScriptプログラムは、その参照を使用して関数を呼び出します。したがって、すべてのJavaScriptプログラム(単一のWebページ内)は同じグローバルオブジェクトを「使用」し、1つの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をスローします(そして結果として壊れます)が、2番目のJavaScriptプログラムは正常に実行されます。もちろん、ブラウザはエラーを報告します(ただし、エラーが発生した後、後続のJavaScriptプログラムを実行しました)。
さて、私の結論は次のとおりです。
- WebページのHTMLコード内のすべてのSCRIPT要素は、個別のJavaScriptプログラムを表します。これらのプログラムは、HTMLパーサーがそれらに遭遇するとすぐに実行されます。
- 同じWebページ内のすべてのJavaScriptプログラムは、同じグローバルオブジェクトを「使用」します。そのグローバルオブジェクトは常に存在します(Webページがフェッチされた瞬間からWebページが破棄されるまで)。JavaScriptプログラムはGlobalオブジェクトを操作する場合があり、1つのJavaScriptプログラムによってGlobalオブジェクトに加えられたすべての変更は、後続のすべてのJavaScriptプログラムで監視できます。
- 1つのJavaScriptプログラムが(エラーがスローされることによって)壊れた場合でも、後続のJavaScriptプログラムの実行が妨げられることはありません。
この投稿を事実確認して、何か問題があったかどうか教えてください。
また、この投稿で言及されている動作を説明するリソースは見つかりませんでした。ブラウザメーカーはそのようなリソースをどこかに公開しているはずなので、それらについて知っている場合は、それらへのリンクを提供してください。