ホームページ  >  に質問  >  本文

javascript - setTimeoutの最初のパラメータは関数をすぐに実行することですが、理解できません

setTimeout の最初のパラメータは関数をすぐに実行するというものですが、理解できません

リーリー

結果は0,1,2,3,4がすぐに出力されるのですが、理由はわかりません

大家讲道理大家讲道理2663日前950

全員に返信(9)返信します

  • 给我你的怀抱

    给我你的怀抱2017-07-05 10:58:26

    このようにして、すべてが一度に印刷されます。 。 。毎秒印刷されるわけではありません。 。このように書くことをお勧めします。 。

    リーリー

    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が渡されます。 この5つの関数が実行されると、iが上方向に検索され、すぐに呼び出される関数のスコープ内でiが見つかることになります。 0、1、2、3、4を出力します

    返事
    0
  • 大家讲道理

    大家讲道理2017-07-05 10:58:26

    まず関数全体を囲む括弧に注目します
    つまり:

    リーリー

    この段落の理解は、自分自身をパッケージ、つまり全体に包み込むことであり、この全体は関数です

    それでは、次に関数を呼び出すにはどうすればよいでしょうか?関数名()はこんな感じでしょうか? 関数名の後に括弧を追加するとパラメータを渡すことができます

    当然のことながら、次のことが起こりました:

    リーリー

    この種の呼び出しでは、関数を作成し、() でラップし、() で続けて、その中にパラメーターを書き込み、直接実行します

    返事
    0
  • 为情所困

    为情所困2017-07-05 10:58:26

    上で述べたように、すぐに出力されますが、setTimeout はまったく効果がありません。
    その理由は、即時実行関数実行後の戻り値がないため、setTimeout(unknown, i*1000)と同等となります。

    返事
    0
  • 迷茫

    迷茫2017-07-05 10:58:26

    setTimeout最初のパラメーターが関数である必要があるため、2 番目のパラメーターで指定された時間が経過した後、最初のパラメーターで定義された関数が実行されます。

    書くとき:

    リーリー

    タイマーはすでに動作していることに気づきますが、1 秒ごとに 1 つしか出力されませんundefined。この関数が実行されると、i はループから飛び出して値を持たないためです。

    これを次のように変更します:

    リーリー

    ただし、この場合、最初のパラメータは関数ではなく式です。つまり、関数はタイマーが有効になるまで待機せず、実行されるとすぐに実行されます。 , したがって、表現形式は 0、1、2、3、4 を直接入力することになります。

    上記のステートメントに従ってこれを次のように変更します:

    リーリー

    最初のパラメータは式ですが、すぐに実行されます。ただし、この式の実行結果は値を出力するのではなく、関数を返します。これは、最初のパラメータが関数であるという setTimeout の要件を満たしています。正しい入力パラメータが設定されているため、正しい結果が 1 秒ごとに出力されます。

    ただし、チームのコラボレーションを考慮すると、このように記述することは一般的にお勧めしません。setTimeout の標準的な記述方法に従って、次のように記述することをお勧めします。 リーリー

    これにより、少なくともグループの他のメンバーが読みやすく、理解しやすくなります。

    返事
    0
  • 我想大声告诉你

    我想大声告诉你2017-07-05 10:58:26

    すぐに実行される関数なので、もちろんすぐに出力されます

    返事
    0
  • 淡淡烟草味

    淡淡烟草味2017-07-05 10:58:26

    関数スコープの問題については、この点を変更するだけです。

    リーリー

    返事
    0
  • 習慣沉默

    習慣沉默2017-07-05 10:58:26

    関数がすぐに実行されない場合、ループが完了するまで setTimeout の関数は実行されないため、5 つの 5 が 1 秒ごとに出力されます。このとき、グローバル変数 i は 5 です。即時実行関数を使用すると、ループ内の各 i が取得されます。この i はローカル変数となり、実行されるたびに変数 i の値が異なります。

    返事
    0
  • 黄舟

    黄舟2017-07-05 10:58:26

    リーリー

    即時実行を宣言0 1 2 3 4です。

    ただし、これには戻り値がないため、デフォルトは

    undefined

    したがって、コードは次のように考えることができます:

    リーリー

    返事
    0
  • 黄舟

    黄舟2017-07-05 10:58:26

    • 原則、クロージャ、スタック、イベントキュー、同期、非同期を理解する

    • 考え方を逆にして、渡したパラメータを削除して、正常に印刷できるかどうかを確認してください。そうでない場合は、その理由を分析してください

    • 上記と同じ効果を得るために書き方を変更できますか?理由を分析してください
      上記のポイントを完了すると、理由、プロセス、結果がわかります

    返事
    0
  • キャンセル返事