再談閉包

    var fnArr = [];
    for (var i = 0; i < 10; i ++) {
        fnArr[i] =  function(){
            return i;
        };
    }
    i = 5
    console.log( fnArr[3]() );  //5

這里居然打出5,為什么不是10呢?為什么不是3呢?有很多人知道i引用的是全局變量i,可以用閉包解決這個問題,那么為什么會這樣呢?還牽扯到了函數(shù)的執(zhí)行原理,因為函數(shù)又是一個對象,對象會被存到堆內存中,所以函數(shù)當函數(shù)沒有執(zhí)行的時候,就把函數(shù)當做字符串放在堆內存中,數(shù)組中存儲的,其實只是指向這個堆內存的指針,i并沒有傳進去,執(zhí)行的時候i才被傳進去

 fnArr[0] =  function(){
     return i
 }
 fnArr[1] =  function(){
     return i
 }

直到函數(shù)執(zhí)行的時候瀏覽器才會解析這段字符串,把他當做函數(shù)來執(zhí)行,所以當我們執(zhí)行函數(shù)的時候,i已經(jīng)循環(huán)到10了,i取到的就是全局變量10,之后我們把i賦值為5,i取到的就是5了。

這時候我們就發(fā)現(xiàn)一個問題,我們想取到每一個i值,怎么辦呢?可以把它放到局部作用域,這時候就輪到閉包大展身手了,閉包的作用就是創(chuàng)建一個局部作用域,保存變量

所以有了之后的一系列的閉包寫法

所以這個題的重點不在于閉包,而在于你對于函數(shù)執(zhí)行了解的程度,如果你能完全理解為什么i變成10,而不是只知道i為10,那么之后寫成閉包就是在自然不過的事了,因為你知道這段代碼有什么問題,那么就只剩解決問題了,可是,程序員的天職不就是解決問題嗎?

最后附一下解決辦法:

方法1:

        //自執(zhí)行函數(shù)
        var fnArr = [];
        for (var i = 0; i < 10; i ++) {
            fnArr[i] =  function(i){
                return function(){
                    return i;
                }
            }(i)
        }
        console.log( fnArr[3]() );  //3

方法2:

        //自執(zhí)行函數(shù)
        var fnArr = [];
        for (var i = 0; i < 10; i ++) {
            fnArr[i] =  (function(){
                var temp = i
                return function(){
                    return temp
                }
            })()
        }
        console.log( fnArr[3]() );  //3

方法3:

        var fnArr = [];
        for (var i = 0; i < 10; i ++) {
            !function(i){
                fnArr[i] =  function(){
                    return i;
                }
            }(i)
            
        }
        console.log( fnArr[3]() );  //3

方法4:

        var fnArr = [];
        for (let i = 0; i < 10; i ++) {
            fnArr[i] =  function(){
                return i;
            };
        }
        console.log( fnArr[3]() );  //3
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 從三月份找實習到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發(fā)崗...
    時芥藍閱讀 42,366評論 11 349
  • 昨晚十點零5分,剛聽完梁小同學《北冥是一種很懸的東西》《不確定的世界 無限可能》準備進入深睡眠時,吳小同學打來電話...
    林a林閱讀 165評論 0 0
  • 最近在折騰MongoDB,在用PHP連接過程中發(fā)現(xiàn)諸多問題,最后選擇用了PHPLIB,也寫下來心酸歷程,以便查閱。...
    我是大彬子閱讀 546評論 0 0
  • 很小的時候,不為了自己,很少哭。看影視劇:親近的人去世了,主角哭得死去活來。我當時暗暗地想,如果我身在其中,哭不出...
    宵夜想換個英文名閱讀 306評論 0 2