javascript - setTimeoutの最初のパラメータは関数をすぐに実行することですが、理解できません
大家讲道理
大家讲道理 2017-07-05 10:56:26
0
9
946

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

リーリー

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

大家讲道理
大家讲道理

光阴似箭催人老,日月如移越少年。

全員に返信(9)
给我你的怀抱

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

リーリー

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
大家讲道理

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

リーリー

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

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

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

リーリー

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

いいねを押す +0
为情所困

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

いいねを押す +0
迷茫

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

書くとき:

リーリー

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

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

リーリー

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

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

リーリー

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

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

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

いいねを押す +0
我想大声告诉你

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

いいねを押す +0
淡淡烟草味

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

リーリー
いいねを押す +0
習慣沉默

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

いいねを押す +0
黄舟

リーリー

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

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

undefined

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

リーリー

いいねを押す +0
黄舟
  • 原則、クロージャ、スタック、イベントキュー、同期、非同期を理解する

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

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

いいねを押す +0
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!