成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

無處不在的閉包

shengguo / 3118人閱讀

摘要:每次循環(huán)都會創(chuàng)建一個以立即執(zhí)行函數(shù)為作用域的變量,原來在程序中函數(shù)訪問的是外部變量,現(xiàn)在訪問的是這一閉包中的變量。

這是篇文章主要是講一下對閉包這一概念的理解。討論閉包之前,我們先從一個經(jīng)典的例子說起

// 程序1
var arr = []
for(var i = 0; i < 3; i++){
    arr[i] = function () {
        console.log(i)
    }
}
arr[0]()  // 3
arr[1]()  // 3
arr[2]()  // 3

大家都知道,這段代碼最終輸出都為3。因為函數(shù)調(diào)用的時候循環(huán)已經(jīng)結(jié)束了所以 i 等于3,更為重要的是,es6之前沒有塊作用域,變量 i 的作用域不在for循環(huán)中,而在for循環(huán)之外。如果我們想要看到輸出結(jié)果依次為0,1,2,就得用到閉包了。否則,除非我們能在每次循環(huán)的過程中調(diào)用函數(shù),因為只有在循環(huán)進行的過程中 i 才會處于0,1,2的狀態(tài)。比如像這樣:

// 程序2
for(var i = 0; i < 3; i++){
    (function () {
        console.log(i)
    })()
}
// 0
// 1
// 2

必須要在循環(huán)進行時調(diào)用哦,像下面這樣都不行!

// 程序3
for(var i = 0; i < 3; i++){
    setTimeout(function () {
        console.log(i)
    }, 0)
}
// 3
// 3
// 3

當(dāng)然程序2這樣寫已經(jīng)失去意義了,這個程序的目的就是要給數(shù)組加幾個函數(shù)供以后調(diào)用,而不是馬上就要調(diào)用它。閉包主要就是用來解決這樣的問題,它讓函數(shù)可以訪問到函數(shù)所被創(chuàng)建時的上下文環(huán)境,不論這個函數(shù)在什么時候被調(diào)用。所以閉包產(chǎn)生的條件有兩個,一是函數(shù)能通過變量作用域規(guī)則訪問到它被創(chuàng)建時的上下文環(huán)境,例如程序1,函數(shù)只是簡單的訪問了外部的變量 i,嚴格上講不算閉包。二是函數(shù)在其它地方執(zhí)行時,函數(shù)依然能夠記住并訪問到它所被定義時的上下文環(huán)境,我們使用閉包來對程序1進行修改:

// 程序4
var arr = []
for(var i = 0; i < 3; i++){
    (function () {
        var j = i
        arr[i] = function () {
            console.log(j)
        }
    })()
}
arr[0]()  // 0
arr[1]()  // 1
arr[2]()  // 2

不同的是這次增加了立即執(zhí)行函數(shù)并在里面定義變量 j ,我們可以把立即執(zhí)行函數(shù)稱為 fn 。每次循環(huán)都會創(chuàng)建一個以立即執(zhí)行函數(shù)為作用域的變量 j ,原來在程序1中函數(shù)訪問的是外部變量 i ,現(xiàn)在訪問的是fn這一閉包中的變量 j 。fn執(zhí)行結(jié)束時 j 本應(yīng)被回收,但是由于該作用域內(nèi)還定義了一個內(nèi)部訪問了變量 j 的函數(shù),該函數(shù)在未來可能被執(zhí)行,所以 j 被“記住”了,也就是作用域鏈被保存了。我們可以把fn稱為一個閉包,閉包內(nèi)可以定義函數(shù)并且這些函數(shù)可以訪問閉包中定義的變量,例如:

function fn(){
    var a = 1;
    return function(){
        console.log(a)
    }
}
var module = fn()
module()  // 1

fn返回的函數(shù)通過閉包能夠訪問到 a。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/105628.html

相關(guān)文章

  • 你不知道JavaScript:閉包

    摘要:回憶我一年前,雖然使用過很多,但卻完全不理解閉包是什么。就算你,也會在循環(huán)完成時,輸出次當(dāng)然,不要以為主要的原因是延遲函數(shù)會在循環(huán)結(jié)束時才執(zhí)行,不然我為什么會在閉包這一節(jié)用使用這個例子,哈哈。 前言 在了解閉包的概念時,我希望你能夠有JavaScript詞法作用域的知識,因為它會讓你更容易讀懂這篇文章。 感觸 對于那些使用過JavaScript但卻完全不理解閉包概念的人來說,理解閉包可...

    weknow619 評論0 收藏0
  • 深入javascript——無處不在this

    摘要:由于匿名函數(shù)的作用域是全局性的,因此閉包的通常指向全局對象調(diào)用返回值為而不是我們預(yù)期的,在閉包中函數(shù)作為某個對象的方法調(diào)用時,要特別注意,該方法內(nèi)部匿名函數(shù)的指向的是全局變量。 有人的地方就有江湖,有函數(shù)的地方就有this。而this在不同的環(huán)境下,又表現(xiàn)為不同的形式,難免讓人有種此this非彼this的疑惑 在java等面向?qū)ο蟮恼Z言中,this指的就是當(dāng)前對象,而在jav...

    Scorpion 評論0 收藏0
  • 重讀你不知道JS (上) 第一節(jié)五章

    摘要:詞法作用域的查找規(guī)則是閉包的一部分。因此的確同閉包息息相關(guān),即使本身并不會真的使用閉包。而上面的創(chuàng)建一個閉包,本質(zhì)上這是將一個塊轉(zhuǎn)換成一個可以被關(guān)閉的作用域。結(jié)合塊級作用域與閉包模塊這個模式在中被稱為模塊。 你不知道的JS(上卷)筆記 你不知道的 JavaScript JavaScript 既是一門充滿吸引力、簡單易用的語言,又是一門具有許多復(fù)雜微妙技術(shù)的語言,即使是經(jīng)驗豐富的 Jav...

    worldligang 評論0 收藏0
  • 我眼中閉包

    閉包,顧名思義就是一個封閉的包裹,你沒辦法窺探到其內(nèi)部,只能通過暴露給你的方法進行操作。其實在寫代碼的過程中,我們可能已經(jīng)使用了閉包,只是當(dāng)時不知道而已。等理解了閉包,再去回顧以前的代碼,就會發(fā)現(xiàn)JavaScript中閉包無處不在。剛開始學(xué)習(xí)閉包的時候,我看過很多關(guān)于閉包的文章,大部分都會舉例這樣一段代碼:showImg(https://segmentfault.com/img/bVO3Mo?w=...

    leeon 評論0 收藏0
  • 云天視角-淺談閉包

    摘要:函數(shù)在執(zhí)行的時候執(zhí)行函數(shù),將當(dāng)前的變量對象由于當(dāng)前的環(huán)境是函數(shù),所以將其活動對象作為變量對象添加到作用域鏈的前端。此時,由于在執(zhí)行,而作用域鏈也存在,所以可以在作用域鏈上進行查找,去訪問的變量。 一、現(xiàn)狀 閉包是jser繞不過的坎,一直在都在說,套用 simpson 的話來說:JavaScript中閉包無處不在,你只需要能夠識別并擁抱它。 閉包是基于詞法作用域書寫代碼時的自然結(jié)果,你甚...

    nanfeiyan 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<