84669 人が学習中
152542 人が学習中
20005 人が学習中
5487 人が学習中
7821 人が学習中
359900 人が学習中
3350 人が学習中
180660 人が学習中
48569 人が学習中
18603 人が学習中
40936 人が学習中
1549 人が学習中
1183 人が学習中
32909 人が学習中
setTimeout の最初のパラメータは関数をすぐに実行するというものですが、理解できません
結果は0,1,2,3,4がすぐに出力されるのですが、理由はわかりません
光阴似箭催人老,日月如移越少年。
このようにして、すべてが一度に印刷されます。 。 。毎秒印刷されるわけではありません。 。このように書くことをお勧めします。 。
0、1、2、3、4 が取得できる理由を説明します。JS の事前解釈に関する記事がインターネット上にたくさんあります。簡単に言うと、次の場合です。この関数を宣言しても、呼び出されない限り実行されません。この関数への参照だけがコンテキストに保存されます。この関数はメモリに保存されるだけであることがわかります。私自身の理解について話させていただきますが、何か間違っている場合はご指摘ください。 関数がすぐに実行されない場合: 実際には for ループで 5 つのタイマーを定義していますが、js はシングルスレッドであり、これらの 5 つの関数は実行を待機するためにキューに配置されます。これら 5 つの関数 function() {console.log(i);} を文字列としてメモリに保存すると、5 つの関数呼び出しが実行されるまで何も起こりません (これは時間切れの setTimeout の 2 番目のパラメーターです)。 、関数内に i があるため、関数の実行が開始されます。このとき、i はスコープ チェーンを通じて検索され、最終的に i はスコープ外で見つかりますが、この時点では for ループが存在します。すでに実行されています。i は 4 になっているので、5 つの 4 が出力されます。 即時実行関数がある場合 (上で書いたものなど): 実際には、for ループで 5 つのタイマーを定義するのと同じです。 , ただし、js はシングルスレッドなので、これら 5 つの関数は実行待ちのキューに置かれます。
(関数(i) { リーリー })(i)
(関数(i) {
})(i)
ただし、外にある関数はすぐに実行されるので、すぐに実行され、iが渡されます。 この5つの関数が実行されると、iが上方向に検索され、すぐに呼び出される関数のスコープ内でiが見つかることになります。 0、1、2、3、4を出力します
まず関数全体を囲む括弧に注目しますつまり:
この段落の理解は、自分自身をパッケージ、つまり全体に包み込むことであり、この全体は関数です
それでは、次に関数を呼び出すにはどうすればよいでしょうか?関数名()はこんな感じでしょうか? 関数名の後に括弧を追加するとパラメータを渡すことができます
当然のことながら、次のことが起こりました:
この種の呼び出しでは、関数を作成し、() でラップし、() で続けて、その中にパラメーターを書き込み、直接実行します
上で述べたように、すぐに出力されますが、setTimeout はまったく効果がありません。 その理由は、即時実行関数実行後の戻り値がないため、setTimeout(unknown, i*1000)と同等となります。
setTimeout最初のパラメーターが関数である必要があるため、2 番目のパラメーターで指定された時間が経過した後、最初のパラメーターで定義された関数が実行されます。
setTimeout
書くとき:
タイマーはすでに動作していることに気づきますが、1 秒ごとに 1 つしか出力されませんundefined。この関数が実行されると、i はループから飛び出して値を持たないためです。
undefined
これを次のように変更します:
ただし、この場合、最初のパラメータは関数ではなく式です。つまり、関数はタイマーが有効になるまで待機せず、実行されるとすぐに実行されます。 , したがって、表現形式は 0、1、2、3、4 を直接入力することになります。
上記のステートメントに従ってこれを次のように変更します:
最初のパラメータは式ですが、すぐに実行されます。ただし、この式の実行結果は値を出力するのではなく、関数を返します。これは、最初のパラメータが関数であるという setTimeout の要件を満たしています。正しい入力パラメータが設定されているため、正しい結果が 1 秒ごとに出力されます。
ただし、チームのコラボレーションを考慮すると、このように記述することは一般的にお勧めしません。setTimeout の標準的な記述方法に従って、次のように記述することをお勧めします。 リーリー
すぐに実行される関数なので、もちろんすぐに出力されます
関数スコープの問題については、この点を変更するだけです。
関数がすぐに実行されない場合、ループが完了するまで setTimeout の関数は実行されないため、5 つの 5 が 1 秒ごとに出力されます。このとき、グローバル変数 i は 5 です。即時実行関数を使用すると、ループ内の各 i が取得されます。この i はローカル変数となり、実行されるたびに変数 i の値が異なります。
リーリー
即時実行を宣言0 1 2 3 4です。
0 1 2 3 4
原則、クロージャ、スタック、イベントキュー、同期、非同期を理解する
考え方を逆にして、渡したパラメータを削除して、正常に印刷できるかどうかを確認してください。そうでない場合は、その理由を分析してください
上記と同じ効果を得るために書き方を変更できますか?理由を分析してください上記のポイントを完了すると、理由、プロセス、結果がわかります
このようにして、すべてが一度に印刷されます。 。 。毎秒印刷されるわけではありません。 。このように書くことをお勧めします。 。
リーリー0、1、2、3、4 が取得できる理由を説明します。
JS の事前解釈に関する記事がインターネット上にたくさんあります。簡単に言うと、次の場合です。この関数を宣言しても、呼び出されない限り実行されません。この関数への参照だけがコンテキストに保存されます。この関数はメモリに保存されるだけであることがわかります。私自身の理解について話させていただきますが、何か間違っている場合はご指摘ください。
関数がすぐに実行されない場合:
実際には for ループで 5 つのタイマーを定義していますが、js はシングルスレッドであり、これらの 5 つの関数は実行を待機するためにキューに配置されます。これら 5 つの関数 function() {console.log(i);} を文字列としてメモリに保存すると、5 つの関数呼び出しが実行されるまで何も起こりません (これは時間切れの setTimeout の 2 番目のパラメーターです)。 、関数内に i があるため、関数の実行が開始されます。このとき、i はスコープ チェーンを通じて検索され、最終的に i はスコープ外で見つかりますが、この時点では for ループが存在します。すでに実行されています。i は 4 になっているので、5 つの 4 が出力されます。
即時実行関数がある場合 (上で書いたものなど):
実際には、for ループで 5 つのタイマーを定義するのと同じです。 , ただし、js はシングルスレッドなので、これら 5 つの関数は実行待ちのキューに置かれます。
ただし、外にある関数はすぐに実行されるので、すぐに実行され、iが渡されます。 この5つの関数が実行されると、iが上方向に検索され、すぐに呼び出される関数のスコープ内でiが見つかることになります。 0、1、2、3、4を出力します
まず関数全体を囲む括弧に注目します
リーリーつまり:
この段落の理解は、自分自身をパッケージ、つまり全体に包み込むことであり、この全体は関数です
それでは、次に関数を呼び出すにはどうすればよいでしょうか?関数名()はこんな感じでしょうか? 関数名の後に括弧を追加するとパラメータを渡すことができます
当然のことながら、次のことが起こりました:
リーリーこの種の呼び出しでは、関数を作成し、() でラップし、() で続けて、その中にパラメーターを書き込み、直接実行します
上で述べたように、すぐに出力されますが、setTimeout はまったく効果がありません。
その理由は、即時実行関数実行後の戻り値がないため、setTimeout(unknown, i*1000)と同等となります。
setTimeout
最初のパラメーターが関数である必要があるため、2 番目のパラメーターで指定された時間が経過した後、最初のパラメーターで定義された関数が実行されます。書くとき:
リーリータイマーはすでに動作していることに気づきますが、1 秒ごとに 1 つしか出力されません
undefined
。この関数が実行されると、i はループから飛び出して値を持たないためです。これを次のように変更します:
リーリーただし、この場合、最初のパラメータは関数ではなく式です。つまり、関数はタイマーが有効になるまで待機せず、実行されるとすぐに実行されます。 , したがって、表現形式は 0、1、2、3、4 を直接入力することになります。
上記のステートメントに従ってこれを次のように変更します:
リーリー最初のパラメータは式ですが、すぐに実行されます。ただし、この式の実行結果は値を出力するのではなく、関数を返します。これは、最初のパラメータが関数であるという setTimeout の要件を満たしています。正しい入力パラメータが設定されているため、正しい結果が 1 秒ごとに出力されます。
ただし、チームのコラボレーションを考慮すると、このように記述することは一般的にお勧めしません。setTimeout の標準的な記述方法に従って、次のように記述することをお勧めします。 リーリー
これにより、少なくともグループの他のメンバーが読みやすく、理解しやすくなります。すぐに実行される関数なので、もちろんすぐに出力されます
関数スコープの問題については、この点を変更するだけです。
リーリー関数がすぐに実行されない場合、ループが完了するまで setTimeout の関数は実行されないため、5 つの 5 が 1 秒ごとに出力されます。このとき、グローバル変数 i は 5 です。即時実行関数を使用すると、ループ内の各 i が取得されます。この i はローカル変数となり、実行されるたびに変数 i の値が異なります。
リーリー
即時実行を宣言
ただし、これには戻り値がないため、デフォルトは0 1 2 3 4
です。
したがって、コードは次のように考えることができます:undefined
リーリー
原則、クロージャ、スタック、イベントキュー、同期、非同期を理解する
考え方を逆にして、渡したパラメータを削除して、正常に印刷できるかどうかを確認してください。そうでない場合は、その理由を分析してください
上記と同じ効果を得るために書き方を変更できますか?理由を分析してください
上記のポイントを完了すると、理由、プロセス、結果がわかります