この投稿の目的は、JavaScript が内部でどのように動作するかを簡単な方法でカバーし、新人プログラマーでも概念を把握し、JavaScript のコーディング時に何が起こるかを視覚化できるようにすることです。
まず、困難を克服し、背後にあるロジックを理解するのに役立つ、焦点を当てたい質問が少なくとも 3 つあります?
これらの質問は、JavaScript が意味する Web 開発者の就職面接で尋ねられる可能性が高い質問でもあります。
1. JavaScript はどのように機能しますか?
2.同期と非同期の違いを説明してください?
3.または、次のステートメントを説明してください: JavaScript はノンブロッキングのシングルスレッド言語ですか?
実際、プログラムを書くために JavaScript が内部でどのように機能するかを知る必要はありませんが、背後で何が起こっているのかを理解し、何を書いているのかを感じるために学ぶことは不可欠かつ重要です。運送業者では、これを知る必要はありません。
まず知ってみましょうプログラムとは何ですか? プログラムとは、コンピューターに何をすべきか、どのようにタスクを実行するかを指示する一連の命令です。プログラムはメモリを割り当てる必要があります。そうしないと、変数を使用したり、コンピューターにファイルを保存したりできなくなります。プログラムは専用のタスクを解析 (読み取り) して実行する必要もあり、すべてがメモリ内で行われます。
さて、JavaScript には、各ブラウザが実装する JavaScript エンジン と呼ばれるエンジンがあります。たとえば、Chrome では V8、Mozilla Firefox では Spider Monkey、Safari ブラウザでは JavaScript Core Webkit.
と呼ばれます。次の画像は Google Chrome の V8 エンジンを示しています
JavaScript エンジン内で何が起こっていますか?
Chrome の V8 などの JavaScript エンジンは、私たちが作成した JavaScript コードを読み取り、ブラウザー用のマシン実行可能命令に変換します。上の図は、メモリ ヒープ ** と **コール スタック の 2 つの部分で構成される JavaScript エンジンの部分を示しています。
メモリ割り当ては メモリ ヒープ で行われ、解析 (読み取り) と実行は 呼び出しスタック で行われることに注意することも重要です。これに加えて、プログラム内のどこにいるのかを示すのはメモリ ヒープです。
JS (JavaScript) コードでメモリ ヒープのメモリ割り当てを見てみましょう
const a = 4; // now we allocated a memory. JS engine is going to remember // that a has a value of 4. const Obj = {a, b, c }; // In memory, variable 'Obj' holds the object {a, b,c} // The same as on array. the engine will remember values of the array const Array = [1,2,3,4,5]
では、グローバルに宣言された上記のコードにはどのような問題があるのでしょうか?
メモリリークと呼ばれるものがあります。上で述べたように、変数の宣言はメモリ ヒープで行われ、割り当てられるサイズには制限があります。数値ではなく非常に大きな配列であり、さらには未使用のグローバル変数を宣言し続けると、メモリがいっぱいになり、メモリ リークが発生します。クリーンアップを忘れるとこのメモリ ヒープがいっぱいになり、最終的にはブラウザが動作できなくなるため、グローバル変数が悪いということを耳にするでしょう。
コールスタックについてはどうですか?
思い出していただければ、スクリプトを読み取って実行するのはコールスタックです。コードを使用して明確にしましょう。
const a = 4; // now we allocated a memory. JS engine is going to remember // that a has a value of 4. const Obj = {a, b, c }; // In memory, variable 'Obj' holds the object {a, b,c} // The same as on array. the engine will remember values of the array const Array = [1,2,3,4,5]
上記のコードでは、コール サックは最初の行 console.log(“x”) を読み取ります。 コール スタックに追加されると、JavaScript エンジンは console.log が追加されたことを認識し、それをコール スタックにポップして実行し、x を出力します。その後、実行が完了した最初の console.log を削除し、2 番目の console.log(“y”) に配置し、呼び出しスタックに追加します。 y を実行し、2 番目の console.log を削除します。最後に、同じプロセスを使用して console.log(“z”) を取得します。
これは最も単純なデモですが、もう少し複雑な例だとどうなるでしょうか?典型的な例を挙げてみましょう:
// Example Call Stak console.log("x"); console.log("y"); console.log("z"); // Result in browser // x // y // z
さて、コールスタックによると、上記のコードで何が起こったでしょうか?上記のコード ブロックがどのように実行されるかを見てみましょう:
//コールスタック
関数 example1() が最初に実行され、次に関数 example2() がコールスタックの最上位に来て実行され、存在するかどうかを確認した後、出力として数値 7 が出力されます。実行する他のコード。この後、console.log(‘7’)、example2()、example1() の順で呼び出しスタックからの削除が開始され、呼び出しスタックは空になります。
>私たちはこの発言を覚えていますか? JavaScript は、ノンブロッキングのシングルスレッド言語です。
シングルスレッド は、呼び出しスタックが 1 つだけ であることを意味します。一度に実行できる処理は 1 つだけであり、呼び出しスタックはスタックと同様に先入れ後出しである ことを強調することが重要です。
他の言語では、マルチスレッドと呼ばれる多数の呼び出しスタックを持つことができます。これは、タスクを待ち続けないようにするために、複数の呼び出しスタックを持つ方が有利である可能性があります。
>しかし、なぜ JavaScript はシングルスレッドになるように設計されたのでしょうか?
この質問に答えると、マルチスレッド環境では複雑なシナリオが発生しないため、通常、シングル スレッドでコードを実行するのは非常に簡単です。実は、気になることが 1 つあります。マルチスレッドでは、デッドロック などの問題が発生する可能性があります。この理論を使えば、同期プログラミングが何を意味するのかを簡単に知ることができます。
同期プログラミングとは簡単に言うと、コードの最初の行が実行され、2 行目が続き、3 行目が実行される、などです…
より明確に言うと、これは、console.log("x") が終了して console.log が発生するまで、console.log("y") を実行できないことを意味します。 (“z”) は 呼び出しであるため、最初の 2 つが両方とも終了するまで開始されませんスタック.
プログラマーは、stackoverflow.com というサイトを使用する可能性があります。名前はどういう意味ですか?良い。見てみましょう:
スタック オーバーフローが発生する仕組み
上の画像は、メモリ リークがどのように発生するか、JavaScript エンジンのメモリ ヒープがどのようにオーバーフローするかを示しています。ここで、コール スタックはサイズを超える多くの入力を受け取り、オーバーフローします。
コードを使用してスタック オーバーフローをデモンストレーションすることができます。
const a = 4; // now we allocated a memory. JS engine is going to remember // that a has a value of 4. const Obj = {a, b, c }; // In memory, variable 'Obj' holds the object {a, b,c} // The same as on array. the engine will remember values of the array const Array = [1,2,3,4,5]
JavaScript はシングルスレッドであり、一度に 1 つのステートメントのみが実行されることに注意してください。 ここで問題が発生します: 次のコード ブロックの console.log(“y”) に、処理に時間がかかる大きなタスクがある場合はどうなるでしょうか。たとえば、数千または数百万の項目を含む配列をループするなどの処理を実行しますか?そこで何が起こるでしょうか?
// Example Call Stak console.log("x"); console.log("y"); console.log("z"); // Result in browser // x // y // z
最初の行が実行され、2 行目に実行すべき大規模なジョブがあると想定されているため、3 行目は実行されるまで長時間待機します。上の例ではこれはあまり意味がありませんが、負荷の高い操作を実行する大規模な Web サイトを考えてみましょう。ユーザーは何もできないでしょう。タスクが完了し、ユーザーがそこで待機するまで、Web サイトはフリーズします。パフォーマンスに関して言えば、これは悪い経験です。
そうですね、同期タスクでは、時間がかかる関数が 1 つあると、それが限界になります。したがって、非ブロッキングなものが必要なようです。上で述べたステートメントを思い出してください: JavaScript は、ノンブロッキングのシングル スレッド言語です。
理想的には、JavaScript では時間のかかるものを待ち続ける必要はありません。では、この問題をどうやって回避すればよいでしょうか?
救済策として、非同期プログラミングがあります。それで、これは何ですか?
非同期は動作のように考えてください。同期実行は予測可能なので優れています。同期では、最初に何が起こるか、次に何が起こるかなどはわかっていますが、遅くなる可能性があります。
画像処理や、API 呼び出しなどのネットワーク経由でのリクエストの実行などを行う必要がある場合、単なる同期タスクではなく、非同期タスクを使用します。
コードを使用して非同期プログラミングを行う方法を見てみましょう:
const a = 4; // now we allocated a memory. JS engine is going to remember // that a has a value of 4. const Obj = {a, b, c }; // In memory, variable 'Obj' holds the object {a, b,c} // The same as on array. the engine will remember values of the array const Array = [1,2,3,4,5]
上記のコードに基づくと、2 行目をスキップして 3 行目を実行し、結果が出力されるまで 3 秒待機しているように見えます。それは非同期の出来事です。
これと何が起こったのかを理解するために、次の図を使用してみましょう。
JavaScript 実行環境
JavaScript を実行するには、メモリ ヒープとコール スタック以上のものが必要です。ブラウザの一部である JavaScript ランタイム と呼ばれるものが必要です。ブラウザに含まれています。図に示すように、エンジンの上部には、Web API と呼ばれる 、コールバック キュー、および イベント ループがあります。
setTimeout 関数を使用するコードについて説明しましょう。
// Example Call Stak console.log("x"); console.log("y"); console.log("z"); // Result in browser // x // y // z
setTimeout 関数 は Web API の一部であり、JavaScript の一部ではありません。代わりに、非同期プログラミングを実行できるようにするためにブラウザーが提供するものです。そこで、説明のためにさらに詳細を説明します。
CALL STACK: console.log(“x”) がコール スタックに入り、実行され、console.log がブラウザに記録されます。その後、setTimeout(() =>{console.log(“y”);},3000);最初のタスクが完了したため、呼び出しスタックに入り、2 番目のタスクに進みます。
ここで問題があります。コードを読み取っているときに、コールスタックは setTimeout 関数 が設定されていることを検出します。これは JavaScript の一部ではなく Web API の一部です (図「JavaScript 実行環境」を参照) には特別な特性があります。何が起こるかというと、setTimeout が WEB API をトリガーし、Web API が通知されるため、関数がコール スタックからポップアウトされます。
Web API は、3 秒以内にタスクを実行する必要があることを認識して、3 秒のタイマーを開始します。ここで、コールスタックが空であるため、JavaScript エンジンは 3 行目の console.log(“z”); に進むことに注意してください。そしてそれを実行します。そのため、結果 x,z が得られましたが、Web API では setTimeout を 3 秒に設定しています。 3 秒後に制限時間が経過すると、setTimeout が実行され、その内容が確認され、完了します。それが完了すると、Web API は setTimeout の callback() 関数があることを認識し、それを実行する準備ができている CALLBACK QUEUE に追加します。
最後の部分である**イベントループ*に来ました。これは、呼び出しスタックが空かどうかを常にチェックし続けます。これが空で、現在 JavaScript エンジンで何も実行されていない場合は、コールバック キューをチェックし、console.log(“z”) を使用して **callback()* 関数を見つけます。それを CALL STACK に配置すると実行されます。完了したら、呼び出しスタックから取り出します。これですべてが空になり、結果 x z y が得られます。
結論: この投稿では、同期および非同期で実行されるタスクの両方の JavaScript ロジックを完全に理解するために、内部で何が起こっているかについて多くの情報を見てきました。
これが高度なロジックを理解する際に始める基礎となるため、これが新人および上級 JavaScript プログラマーが ReactJS や AngularJS などの JavaScript 関連フレームワークでのコーディングを楽しむのに役立つことを願っています。
>ハッピーコーディング
参考文献
https://www.freecodecamp.org/news/how-javascript-works-behind-the-scenes.
https://www.simplelearn.com/tutorials/javascript-tutorial/callback-function-in-javascript#
以上がJavaScript は内部でどのように動作するのでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。