JavaScript の実行順序
JavaScript は、コードが上から下へと順番に実行される、いわゆる「同期処理」の言語として知られています。しかし、実際には様々な要素が絡み合い、より複雑な実行順序で処理が行われています。
基本的な実行フロー
JavaScript では、関数が呼び出されると、その関数内のコードが順番に実行されます。 内部で別の関数が呼び出された場合、その関数も同様に順番に評価されるため、関数の中に別の関数がある場合、内側の関数から順に外側の関数まで評価される形で進みます。
<script>
function sayHello() {
console.log("こんにちは!");
}
function greet() {
console.log("初めまして、");
sayHello();
console.log("よろしくお願いします。");
}
greet();
</script>
上記のコードでは、greet()
関数が呼び出されると、以下の順序で実行されます。
greet()
関数内の最初のconsole.log("初めまして、")
が実行されます。sayHello()
関数が呼び出され、console.log("こんにちは!")
が実行されます。sayHello()
関数の処理が終了し、greet()
関数内の処理に戻ります。greet()
関数内の最後のconsole.log("よろしくお願いします。")
が実行されます。
コールスタック
JavaScript は、関数の呼び出しを管理するために「コールスタック」という仕組みを使います。関数が呼び出されると、その関数がスタックに積まれ、処理が終了するとスタックから取り除かれます。このため、内側の関数から外側の関数へと順番に処理が進んでいきます。
イベントループと非同期処理
JavaScript は、タイマーやイベント処理など、非同期処理を行うための機能も備えています。これらの処理は、イベントループと呼ばれる仕組みによって管理されます。
イベントループは、大きく分けて以下の手順で動作します。
- コールスタックが空になるまで、スタック内の関数を順番に実行します。
- コールスタックが空になると、イベントキューに登録されているイベントがあれば、それを取り出して処理します。
- イベントの処理が完了すると、再び手順1に戻ります。
タイマーやイベントリスナーなどは、イベントキューに登録され、コールスタックが空になったタイミングで実行されます。そのため、これらの処理は、記述されている位置に関わらず、他の同期処理の後に実行されることになります。
まとめ
JavaScript の実行順序は、一見単純に見えますが、コールスタックやイベントループなどの仕組みによって複雑に制御されています。非同期処理を含むコードを扱う場合、これらの仕組みを理解しておくことが重要です。
参考文献
Q&A
Q1: JavaScript で非同期処理を行うには、どのような方法がありますか?
A1: setTimeout関数やsetInterval関数を使ったタイマー処理、addEventListener関数を使ったイベントリスナーの登録、Promiseオブジェクトやasync/await構文を使った非同期処理など、様々な方法があります。
Q2: コールスタックのオーバーフローは、どのような場合に発生しますか?
A2: 再帰関数のように、関数が自分自身を呼び出す処理を繰り返すと、コールスタックに積み重なる関数の数が限界を超えてしまい、オーバーフローが発生します。
Q3: イベントループとは、具体的にどのような役割を担っていますか?
A3: JavaScript エンジンはシングルスレッドで動作するため、一度に実行できる処理は一つだけです。イベントループは、非同期処理をキューに登録し、順番に実行することで、ブロッキングが発生しないように処理を管理しています。
その他の参考記事:JavaScript ステートメント