前端初學(xué)-閉包相關(guān)

本人所有文章均為學(xué)習(xí)過程中的總結(jié),不同程度地參考了互聯(lián)網(wǎng)上其他的文章,如果不正懇請指出,共同進步

閉包

我們有一些數(shù)據(jù)需要放在一個私有空間--->我們發(fā)現(xiàn)函數(shù)的作用域是私有的(塊級作用域)--->我們創(chuàng)建了一個函數(shù)--->里面有我們存放的私密數(shù)據(jù)--->執(zhí)行這個函數(shù),私密數(shù)據(jù)創(chuàng)建并初始化--->我們需要通過一些特殊的方法在公共空間訪問函數(shù)里面的數(shù)據(jù)--->閉包

  • 閉包:當(dāng)函數(shù)可以記住并訪問所在的作用域(全局作用域除外)時,就產(chǎn)生了閉包,即使函數(shù)是在當(dāng)前作用域之外執(zhí)行.
  • 為什么要使用閉包:通過函數(shù)創(chuàng)建的作用域形成私有空間保護數(shù)據(jù),在函數(shù)外部訪問函數(shù)內(nèi)部的數(shù)據(jù),只有通過函數(shù)內(nèi)部提供的方法有限制地進行訪問和更改(在提供的方法中可以設(shè)置一些校驗安全措施之類的邏輯,保證系統(tǒng)的穩(wěn)定性).
  • 閉包要解決什么問題:
    1. 由于作用域訪問原則,上級作用域無法訪問下級作用域的成員(可以通過return獲取下級作用域內(nèi)部數(shù)據(jù),存在諸多問題)
    2. 要解決的問題就是允許外部訪問并修改函數(shù)內(nèi)部的數(shù)據(jù)
  • 使用閉包的難點:如何花式將內(nèi)部函數(shù)拋到全局作用域去?

由于作用域的限制,在使用閉包之前,函數(shù)是封閉的,當(dāng)我們使用某種方式構(gòu)造了閉包環(huán)境之后,此函數(shù)的成員可以在該函數(shù)外部訪問到.

簡單來說,假設(shè)函數(shù)A在函數(shù)B的內(nèi)部進行了定義,并且當(dāng)函數(shù)A在執(zhí)行時,訪問了函數(shù)B內(nèi)部的變量對象,那么A和B組合構(gòu)造了閉包環(huán)境,此處網(wǎng)上眾說紛紜,用人說B是閉包,有人說A是閉包,筆者水平有限,不考慮誰是閉包,最終目的是訪問B中的成員,筆者較為信服的說法是,接受B函數(shù)返回值A(chǔ)函數(shù)的變量才真正是閉包函數(shù).

以后在筆者文章里,閉包只是一種手段,作動詞,構(gòu)造閉包環(huán)境,不指代任何函數(shù).

"閉包"的字面意思與其實際的作用恰恰相反,函數(shù)本來是封閉的,當(dāng)其成為閉包反而突破了封閉.

  • 閉包原理:
    1. f1內(nèi)部的函數(shù)f2可以訪問其外部函數(shù)f1的成員
    2. 在f1外部訪問f2則可以達到外部訪問f1內(nèi)部成員的目的
    function f1(){
        var num=123;
        var f2=function(a){
            if(a!==undefined){//如果傳參 set
                 num=a;
            }else{
                 return num;//如果不傳參 get
            }
        }
        return f2;
    }

    var foo=f1();//foo=f2
    foo(10);//f2(10); set
    console.log(foo()); get

這個例子中f1 f2組合構(gòu)建了閉包環(huán)境,foo是真正的閉包函數(shù)

  • 使用閉包獲取并設(shè)置多個數(shù)據(jù) (利用對象,將多個內(nèi)部函數(shù)封裝在對象內(nèi)拋出)
    function f(){
        var name="zzw";
        var age="18";

        var o = {
            setName:function(a){
                name=a;
            },
            getName:function(){
                return name;
            },
            setAge:function(a){
                age=a;
            },
            getAge:function(){
                return age;
            }
        }
        return o;
    }

        var o = f();//執(zhí)行函數(shù),創(chuàng)建初始化私有變量,同時將特權(quán)方法全都拋出
        var getName=o.getName;
        var getAge=o.getAge;
        var setName=o.setName;
        var setAge=o.setAge;

其實我們可以將以上代碼簡化
這樣創(chuàng)建的函數(shù)f的內(nèi)部變量(name,age)的創(chuàng)建以及初始化還要手動調(diào)用該函數(shù)f(),我們理想的狀態(tài)是:創(chuàng)造出一個空間,里面可以直接執(zhí)行變量創(chuàng)建以及初始化等語句,并且將包含特權(quán)方法的對象拋出,而不需要我們手動調(diào)用函數(shù).

  • 解決辦法:創(chuàng)建一個匿名函數(shù)并立刻執(zhí)行該函數(shù)(必須加上括號,不然會被理解成函數(shù)聲明,加上括號則是函數(shù)表達式,不會被提升),這樣我們就創(chuàng)建了一個塊級作用域.

以下這段代碼同上面的代碼效果相同,使得邏輯更加清晰,弱化了外部函數(shù),著眼于塊級作用域.

        var o=(function(){
            var name="zzw";//私有變量
            var age="18";//私有變量
            //這里面就是一個塊級作用域,外部如果不通過特權(quán)方法對象則無法訪問
            var o = {//特權(quán)對象
                    setName:function(a){  //特權(quán)方法1
                        name=a;
                    },
                    getName:function(){   //特權(quán)方法2
                        return name;
                    },
                    setAge:function(a){   //特權(quán)方法3
                        age=a;
                    },
                    getAge:function(){    //特權(quán)方法4
                        return age;
                    }
                }
                return o;
        })();

        var getName=o.getName;
        var getAge=o.getAge;
        var setName=o.setName;
        var setAge=o.setAge;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖俄讹,帶你破解...
    沈念sama閱讀 221,430評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡翅帜,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評論 3 398
  • 文/潘曉璐 我一進店門命满,熙熙樓的掌柜王于貴愁眉苦臉地迎上來涝滴,“玉大人,你說我怎么就攤上這事胶台〖叽” “怎么了?”我有些...
    開封第一講書人閱讀 167,834評論 0 360
  • 文/不壞的土叔 我叫張陵诈唬,是天一觀的道長韩脏。 經(jīng)常有香客問我,道長铸磅,這世上最難降的妖魔是什么赡矢? 我笑而不...
    開封第一講書人閱讀 59,543評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮阅仔,結(jié)果婚禮上吹散,老公的妹妹穿的比我還像新娘。我一直安慰自己八酒,他們只是感情好空民,可當(dāng)我...
    茶點故事閱讀 68,547評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著丘跌,像睡著了一般袭景。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上闭树,一...
    開封第一講書人閱讀 52,196評論 1 308
  • 那天耸棒,我揣著相機與錄音,去河邊找鬼报辱。 笑死与殃,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播幅疼,決...
    沈念sama閱讀 40,776評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼米奸,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了爽篷?” 一聲冷哼從身側(cè)響起悴晰,我...
    開封第一講書人閱讀 39,671評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎逐工,沒想到半個月后铡溪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,221評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡泪喊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,303評論 3 340
  • 正文 我和宋清朗相戀三年棕硫,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片袒啼。...
    茶點故事閱讀 40,444評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡哈扮,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蚓再,到底是詐尸還是另有隱情滑肉,我是刑警寧澤,帶...
    沈念sama閱讀 36,134評論 5 350
  • 正文 年R本政府宣布对途,位于F島的核電站赦邻,受9級特大地震影響髓棋,放射性物質(zhì)發(fā)生泄漏实檀。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,810評論 3 333
  • 文/蒙蒙 一按声、第九天 我趴在偏房一處隱蔽的房頂上張望膳犹。 院中可真熱鬧,春花似錦签则、人聲如沸须床。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,285評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽豺旬。三九已至,卻和暖如春柒凉,著一層夾襖步出監(jiān)牢的瞬間族阅,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,399評論 1 272
  • 我被黑心中介騙來泰國打工膝捞, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留坦刀,地道東北人。 一個月前我還...
    沈念sama閱讀 48,837評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像鲤遥,于是被迫代替她去往敵國和親沐寺。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,455評論 2 359

推薦閱讀更多精彩內(nèi)容