以下のコードの最初のfor文の実行結果は「5」が5回出力される形となります。
何故、0から順に5まで出力されず「5」が5回出力されるのでしょうか?
for (var i = 0; i < 5; i++) { setTimeout(function () { console.log(i); }, 1); }; for (let n = 0; n < 5; n++) { setTimeout(function () { console.log(n); }, 1); };
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答2件
0
何故、0から順に5まで出力されず「5」が5回出力されるのでしょうか?
- JavaScriptはシングルスレッド動作なので、同時に複数コードを実行出来ません(Service Worker を除く)
- シングルスレッドなので、実行完了するまで余所のコード実行を待機させます
- シングルスレッドなので、同期コード/非同期コードはそれぞれ実行開始から実行完了まで連続処理されます(割込処理は働きません)
for
文は同期コード、setTimeout
は非同期コードなので、
- 先に実行された
for
の処理を完了まで実行する setTimeout
のタイマー処理が働く
という処理順になります。
2つ目のfor文では何故、0~4までの数値を出力するのでしょうか...?
4つの変数か各々、独立したスコープを持っているからです。
Re: aae_11 さん
投稿2019/08/14 23:49
編集2019/08/15 03:41総合スコア18156
0
ベストアンサー
FAQですね。
var変数の箱は1つだけでlet変数の箱はループブロックの数だけいっぱいあります。
最初のfor文はsetTimeoutの時間差後に1つのvar変数(ループ終了後に5になる)を出力しています。
コメントの回答
自分の認識では、varが0の時setitimeout関数が実行され、console.log(i)によって「0」が出力されると思うのですが、そうではないのでしょうか...?
setitimeout関数はdelayミリ秒の後にfunctionを実行するものです。
var timeoutID = scope.setTimeout(function[, delay]);
WindowOrWorkerGlobalScope.setTimeout() - Web API | MDN
setTimeout(function () { console.log(i); }, 1);
で1ミリ秒後(1秒の1/1000)にしていることが理解を妨げていると思います。
setTimeout(function () { console.log(i); }, 2000);
として2000ミリ秒後(2秒後)にしましょう。
varが0の時setitimeout関数が実行され、console.log(i)によって「0」が出力されると思うのですが、そうではないのでしょうか...?
コンピューターの計算は爆速ですから、2秒後にはfor文のvar i=0からi=4まで実行されて終わっています。
setitimeout関数は指定ミリ秒後にfunctionを実行するものです。
varが0の時setitimeout関数は実行しますがfunctionの中身は実行しません。
functionの中身を実行するのは指定ミリ秒後です。
指定ミリ秒後が2秒後とすれば、2秒後にはvar変数の値は5になっています。
しかし、そうなりますと疑問な点が生じてしまうのですが、何故、質問本文に記載させて頂きましたコードの2つ目のfor文(letを使用している方)の場合では、0から4が順に出力されることになるのでしょうか?
変数letはブロックスコープだからと思います。
変数letのときforループのループブロックごとに別の箱(メモリの場所)が用意されます。
同じ変数letでも別の箱を見ています。
変数にletを使うことでプログラムに不具合が起きにくくなるようです。
こちらは別の回答のために作成した図です。
varは1つの箱を使いまわしして、letは箱をいっぱい作ると理解しています。
投稿2019/08/14 14:26
編集2019/08/15 15:32総合スコア777
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/08/15 08:16
2019/08/15 09:44
2019/08/15 09:56
2019/08/15 15:32
2019/08/16 01:59
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/08/15 00:36
2019/08/15 03:42
2019/08/15 04:17
2019/08/15 09:58