js閉包結合定時器的題目詳解(面試題之一)

function fn1(){
    for(var i=0;i<4;i++){
        var tc = setTimeout(function(i){
            console.log(i);
            clearTimeout(tc)
        },10,i)
    }
    
}    
function fn2(){
        for(var i=0;i<4;i++){
            var tc = setInterval(function(i,tc){
                console.log(i);
                clearInterval(tc)
            },10,i,tc) 
        }
    }
fn1();
fn2();

學習過程當中遇到這樣一個題目,第一眼看很懵逼,第二眼也懵逼,第三眼更懵逼,你們能夠發動你的想象力猜一猜正確答案是多少,反正我是沒猜對。函數


接下來,我分享一下我順着答案,猜過程的調試過程吧,順便揭曉一下答案學習

fn1()//0,1,2
fn2()//0,1,2,3,3,3,3,3,...全是3

爲毛是這樣的結果呢,你們對比一下兩個函數有什麼不一樣,仔細看發現兩點spa

  1. 一個是setTimeout,一個是setInterval,這個區別致使後面結果中,最後一輸出3
  2. 定時器後面的參數不同,setInterval多一個tc參數,而且匿名函數中接受了這個tc參數(敲黑板,劃重點!!!),對定時器傳參不明白的點擊進去看https://developer.mozilla.org...

對fn1函數稍稍改變一下呢 3d

圖片描述

在定時函數外面tc能正常打印,可是定時器裏面tc一直是最後一個值,這是爲何呢?調試

如上圖,能夠看出函數執行順序,在第一個定時器裏的函數執行時,tc變量保存在內存中的值是6449,也就是最後一個定時器的id,setTimeout中的函數每次訪問的即是tc變量內存中的6449,因此每次都是清除的最後一個定時器,最後一個定時器還沒執行就已經被清除了,因此最後打印出0,1,2code


但願能輸出0,1,2,3咋辦呢blog

clipboard.png

將tc做爲變量傳入,函數內部是容許訪問函數外部的值的,每一次清除的定時器都是上一次執行後的定時器,fn2()也能夠同理分析圖片

相關文章
相關標籤/搜索