亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

setTimeout第一個參數是立即執行函數,看不懂了

setTimeout第一個參數是立即執行函數,看不懂了

慕工程0101907 2018-11-14 18:43:28
setTimeout第一個參數是立即執行函數,看不懂了for (var i = 0; i < 5; i++) {  setTimeout((function(i) {    console.log(i);  })(i), i * 1000);}雖然結果是立即輸出0,1,2,3,4,但是不知道為啥
查看完整描述

1 回答

?
慕俠2389804

TA貢獻1719條經驗 獲得超6個贊

這樣其實是一下子全部打印出來的。。。不是每隔一秒打印出來。。建議這樣寫。。

for (var i = 0; i < 5; i++) {

  setTimeout((function(i) {

    return function() {

        console.log(i);

    }

  })(i), i * 1000);

}

我來解釋一下這個為什么可以獲取到0、1、2、3、4.
網上關于JS預解釋的文章也不少,在進入執行上下文階段的時候函數并不會執行,簡單來說就是當你聲明這個函數的時候,只要不調用就不會執行,上下文里面只會保存著這個函數的引用,可以看做這個函數保存在內存中,只有到調用的時候函數才會執行,我說說自己的理解,有不對的地方請指出來。
如果沒有立即執行函數:
你在for循環里面實際上相當于定義了5個定時器,但是js是單線程,這五個函數會被放到隊列里面等待執行,舉個不一定恰當的例子,你就把這五個函數function() {console.log(i);}當成字符串保存到內存中,一直沒什么動靜,等到這五個函數調用執行的時候(就是setTimeout的第二個參數的時間到了的時候),才會開始執行這個函數,因為函數里面有個i,這個時候會通過作用域鏈來查找這個i,最后在外面的作用域里面查找到了i,但是這個時候for循環已經執行結束了,i已經變成4了,所以會打印出5個4.
如果有立即執行函數(比如我上面寫的那個):
你在for循環里面實際上相當于定義了5個定時器,但是js是單線程,這五個函數會被放到隊列里面等待執行。

(function(i) {

return function() {
    console.log(i);
}

})(i)

但是由于外面是立即執行函數,所以會立即就執行了,并且把i傳了進去,等到這五個函數執行的時候,向上查找i,正好在這個立即調用函數的作用域里面查找到了i,所以會打印出0、1、2、3、4.


查看完整回答
反對 回復 2018-12-15
  • 1 回答
  • 0 關注
  • 1268 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號