关于setTimeout的一道经典面试题
生活随笔
收集整理的這篇文章主要介紹了
关于setTimeout的一道经典面试题
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
想必大家都見過這一道經典的面試題:
for (var i = 1; i <= 5; i++) {setTimeout(function test() {console.log(i) // 依次輸出:6 6 6 6 6}, i * 1000); }造成這個現象的原因是等到setTimeout異步執行時,i已經變成6了。(不了解的小伙伴可以去看下JS事件循環機制(Even Loop))
那么如何使他輸出: 1,2,3,4,5呢?
1.閉包, 保存變量
for (var i = 1; i <= 5; i++) {(function (i) {setTimeout(function () {console.log('閉包:', i); // 依次輸出:1 2 3 4 5}, i * 1000);}(i)); }在這里創建了一個閉包,每次循環都會把i的最新值傳進去,然后被閉包保存起來。
2.bind
for (var i = 1; i <= 5; i++) {// 緩存參數setTimeout(function (i) {console.log('bind', i) // 依次輸出:1 2 3 4 5}.bind(null, i), i * 1000); }實際上這里也用了閉包,我們知道bind會返回一個函數,這個函數也是閉包。
它保存了函數的this指向、初始參數,每次i的變更都會被bind的閉包存起來,所以輸出1-5。
3.let
用let聲明i也可以輸出1-5: 因為let是塊級作用域,所以每次都會創建一個新的變量,所以setTimeout每次讀的值都是不同的。
總結
以上是生活随笔為你收集整理的关于setTimeout的一道经典面试题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: lacewing简介
- 下一篇: 【最多颜色的车辆】