從 setTimeout 完全理解閉包

先看一個常見的例子
setTimeout 閉包代碼閉包

//代碼段(1)

for(var i=0;i<5;i++){
    setTimeout(console.log.bind(null,i),i*1000);
}

輸出: 打印爲每間隔1s依次遞增打印i。函數

疑問: 若是把bind改爲call將會是什麼效果呢?this

//代碼段(2)內部打印函數當即自執行

for(var i=0;i<5;i++){
    setTimeout(console.log.call(null,i),i*1000);
}

輸出: 一次性所有打印遞增i,並未達到計時器效果。code

原理解釋:
bind(arg1,arg2,arg3...),call(arg1,arg2,arg3...)函數,arg1做用爲更改this指向,其他arguments爲預設值。
區別: bind函數並不會當即執行,而call函數會當即執行。這就是爲何call函數會一次性打印的緣由。io

//代碼段(3)
 //代碼段 (3) == 代碼段(1)
for(var i=0;i<5;i++){
    setTimeout(function(index){
      console.log(index);
    }.bind(null,i),i*1000);
}
//代碼段 (4)內部打印函數當即自執行
//代碼段 (4)== 代碼段(2)
for(var i=0;i<5;i++){
    setTimeout((function(index){
      console.log(index);
    }.bind(null,i))(i),i*1000);
}

若是想用call函數,可是阻止自執行腫麼辦捏?很簡單,內部再加個function做爲返回值console

for(var i=0;i<10;i++){
    setTimeout(function(index){
      return function(){ 
        console.log(index); 
      }
    }.call(null,i),i*1000);
}
相關文章
相關標籤/搜索