1. 程式人生 > 其它 >HTTP請求流程詳解

HTTP請求流程詳解

害,作為js三座大山中的一座泰山,閉包屬實困擾了很多登山的同志,今天我也想來挑戰挑戰這座大山。但是雲深不知處,只緣身在此山中,你可能覺得你還在山腰,卻可能快接近山巔,你以為你到了山巔,卻不知還在山腳,因此我這篇對於閉包討論的文章,可能存在諸多偏頗,還請諒解,如有更好更精妙的意見,可在評論區中與我一起討論。PS:我只是個小菜雞。

既然是討論閉包,那麼我們就得先知道他的概念:閉包就是能夠讀取其他函式內部變數的函式。這是百度百科給出的定義,由此一句話屬實難過,這啥呀這是,你玩不起,你小垃圾,抱歉,抖音中毒了,迴歸正題。

我認為閉包需要兩個組成部分:[函式 + 變數];

該概念我是於一位大佬的這篇文章

中看到的,覺得甚是精妙。

先看程式碼:

function fn1(){
    var monkey='薰悟空';
    function fn2(){
        console.log(monkey)
    }
    return fn2;
}
var a=fn1();
a()

這就是一個最簡單的閉包,請注意,我是說函式f2加上內部列印的monkey變數合起來是一個閉包,不是說這一個整體,也不是單純說函式f2,因為根據概念,閉包能夠讀取其他函式內部的變數,如果你去掉了對於變數monkey的列印,那麼也就失去了對於變數monkey的讀取,那麼這無法形成一個閉包。

那麼上面這個閉包起到了什麼作用呢?他讓定義在全域性作用域下的a讀取到了函式f1內部的私有變數monkey,這就是閉包的一個特點。

那麼經常有人說閉包和return共生,有閉包一定有return,其實不然,閉包與return無關,那麼有人就會說了,你不return就無法訪問到這個閉包。其實return只是暴露出這個閉包,讓你能夠訪問而已。它和閉包無絕對關係,因為你也可以這麼寫:

function fn1() {
    var monkey = '薰悟空';
    window.fn2 = function () {
         console.log(monkey)
    }
}
fn1();
fn2();

或者這麼寫:

var fn2;
function fn1() {
    var monkey = '薰悟空';
    fn2 
= function () { monkey = '逼馬吻'; console.log(monkey) } } fn1(); fn2();

這兩種寫法中函式f2加上內部訪問的變數monkey依舊是一個閉包。

閉包有什麼作用呢?閉包通常用來間接訪問一個變數,或者說隱藏一個變數。

見程式碼:

function monkey() {
     var name = '石猴兒';
     window.puti=function () {
          name = '薰悟空';
     }
}
monkey();
puti();

就說天地生的一個石猴兒,想要換一個名字,好,大家都來了,這給鬥戰勝佛取名字多威風啊,結果這個性情剛烈的猴兒說猴可殺不可辱,你們這些凡夫俗子豈能給我取名字,我的名字只能由菩提老祖來取,好,最後菩提老祖說時候事多,賞了石猴三個腦瓜崩,給石猴兒取名薰悟空。

上面例子中石猴兒的名字是石猴兒的私有存在,其他人碰不得,不能碰,只能夠由石猴兒認可的菩提老祖才能更改,由此菩提老祖加上對石猴兒名字的訪問權就形成了一個閉包,只能通過他來間接訪問石猴兒的名字。

為什麼通常閉包都是函式巢狀函式呢,因為有函式的定義和作用決定:定義:訪問函式內部的變數;作用:間接訪問。如果不是函式巢狀函式,而是下面這種情況:

var name = '石猴兒';
function puti () {
    name = '薰悟空';
}
puti();

這個時候的puti加上對name變數就不是一個閉包,因為name變數處於全域性作用域下,誰都可以訪問,沒有達到通過puti間接訪問的目的。所以閉包的出現通常都是函式套函式。