閉包

作用域鏈

要學習閉包筷笨,首先要了解作用域鏈

作用域鏈:環(huán)境對象中定義的變量,會放到作用域中,形成一個鏈式結構。

定義三個變量 a b c 使其在不同的作用域

var a = 10;
        function F() {
            var b = 20;
            //內部函數(shù):函數(shù)內部定義的函數(shù)
            function N() {
                var c = 30;
                return a + b + c;
            }
            return N();
        }
        

        //驗證N中是否都能使用所有的鏈上變量
        console.log(F());//60

在變量 c 的作用域中叮趴,可以調用到 a b 在 b 的作用域中,可以調用到 a
但是反向就不能實現(xiàn)权烧,a 的作用域中無法調用 b c 眯亦,b的作用域中 無法調用 c

如果我們想在變量作用域中訪問其子作用域中定義的變量,要怎樣實現(xiàn)呢般码?閉包的使用能解決這個問題


利用閉包突破作用域鏈

首先來看閉包的概念

閉包的概念妻率、優(yōu)點、缺點.png

閉包的原理就是在被訪問的變量a的作用域中創(chuàng)建一個函數(shù)板祝,將需要訪問的變量當做新創(chuàng)建的函數(shù)返回值宫静,再將函數(shù)定義給最外層的變量b,就能通過執(zhí)行變量b來訪問到變量a

原理如圖:

利用閉包突破作用域鏈.png

代碼如下:

//第一種寫法
var a = 10;
        function F() {
            var b = 20;
            function N(){
                return b
            }
            return N;
        }
        var M = F();
        console.log(M());

        // 原理一樣,寫法不一樣囊嘉,第二種寫法
        var inner;
        var a = 10;
        function F() {
            var b = 20;
            function N(){
                return b
            }
            inner = N;
        }
        F();
        console.log(inner());

不過需要注意:

閉包會常駐內存温技,使用需要謹慎

閉包的概念清楚了,下面來講一下閉包的應用


閉包的應用1

循環(huán)中的閉包

我們可以試著將函數(shù)里循環(huán)中的每一個變量拿出來扭粱。

敲一下代碼:

 function F() {
            var arr = [];

            for (var i = 0; i < 3; i++) {
                arr[i] = function(){
                    return i;
                };
            }
            return arr;
         }

         var str = F();

         console.log(str[0](), str[1](), str[2]());//3 3 3 

咦?什么鬼震檩,怎么出現(xiàn)了三個一樣的數(shù)

分析一下琢蛤,不難發(fā)現(xiàn),arr[i]中保存的是 i 抛虏, i 是相當于直接定義在 F 函數(shù)的作用域中博其,執(zhí)行完 F 函數(shù) i 的值直接就已經(jīng)變?yōu)?3 ,這樣迂猴,我們就應該在循環(huán)的時候慕淡,就把數(shù)組里的值保存下來,這樣就對了

閉包本身不保存上一作用域中變量的值沸毁,當使用時是去上面的作用域中查找相同名字變量峰髓,使用最近那一層作用域中的變量

修改代碼如下:

function F() {
            var arr = [];

            for (var i = 0; i < 3; i++) {
                arr[i] = (function(x){
                    return function(){
                        return x;
                    };
                })(i);
            }
            return arr;
        }

        var str = F();

        console.log(str[0](), str[1](), str[2]());//0 1 2

也有原理圖,在此:

2.png

這樣就能保存到我們想要的數(shù)據(jù)了


閉包的應用2

getter 和 setter

有時候息尺,為了變量的安全考慮携兵,我們一般會不讓變量直接被訪問到
就可以利用閉包來實現(xiàn)

看看代碼:

var setNum;
var getNum;


        (function(){
            var num = 0;

            //setter方法
            setNum = function(x) {
                //安全的考慮
                if (typeof x === "number") {
                    num = x;
                }
            };

            //getter方法
            getNum = function() {
                return num;
            };

        })();

        console.log(num);//0

        setNum(100);
        console.log(getNum());//100

這樣的話,直接訪問 num 是訪問不到的搂誉,同時要修改 num 的值也不能直接修改徐紧,通過閉包的方法,我們還能控制賦給變量新賦值的類型


閉包的應用3

迭代器

迭代: 一個一個尋找下一個目標

知道遍歷簡單的數(shù)組炭懊,以后便利的數(shù)據(jù)結構可能比較復雜

使用“下一個是誰”的想法去遍歷

代碼如下:

var arr  = [1,2,3,4,5];

        function setUp(x) {
            var i = 0;
            return function (){
                if(x.length == i-1){
                    i = 0;
                }
                return x[i++];
            }
        }

        var next = setUp(arr);
        console.log(next());//1
        console.log(next());//2
        console.log(next());//3
        console.log(next());//4
        console.log(next());//5

        console.log(next());//undefined
        console.log(next());//1
        console.log(next());//2

這樣就實現(xiàn)了迭代的方法并级,一次一次找到下一個值


最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市侮腹,隨后出現(xiàn)的幾起案子嘲碧,更是在濱河造成了極大的恐慌,老刑警劉巖凯旋,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件呀潭,死亡現(xiàn)場離奇詭異,居然都是意外死亡至非,警方通過查閱死者的電腦和手機钠署,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來荒椭,“玉大人谐鼎,你說我怎么就攤上這事∪せ荩” “怎么了狸棍?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵身害,是天一觀的道長。 經(jīng)常有香客問我草戈,道長塌鸯,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任唐片,我火速辦了婚禮丙猬,結果婚禮上,老公的妹妹穿的比我還像新娘费韭。我一直安慰自己茧球,他們只是感情好,可當我...
    茶點故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布星持。 她就那樣靜靜地躺著抢埋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪督暂。 梳的紋絲不亂的頭發(fā)上揪垄,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天,我揣著相機與錄音损痰,去河邊找鬼福侈。 笑死,一個胖子當著我的面吹牛卢未,可吹牛的內容都是我干的肪凛。 我是一名探鬼主播,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼辽社,長吁一口氣:“原來是場噩夢啊……” “哼伟墙!你這毒婦竟也來了?” 一聲冷哼從身側響起滴铅,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤戳葵,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后汉匙,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拱烁,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年噩翠,在試婚紗的時候發(fā)現(xiàn)自己被綠了戏自。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡伤锚,死狀恐怖擅笔,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤猛们,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布念脯,位于F島的核電站,受9級特大地震影響弯淘,放射性物質發(fā)生泄漏绿店。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一庐橙、第九天 我趴在偏房一處隱蔽的房頂上張望惯吕。 院中可真熱鬧,春花似錦怕午、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至甲锡,卻和暖如春兆蕉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背缤沦。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工虎韵, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人缸废。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓包蓝,卻偏偏與公主長得像,于是被迫代替她去往敵國和親企量。 傳聞我的和親對象是個殘疾皇子测萎,可洞房花燭夜當晚...
    茶點故事閱讀 44,941評論 2 355

推薦閱讀更多精彩內容

  • 本章將會介紹 閉包表達式尾隨閉包值捕獲閉包是引用類型逃逸閉包自動閉包枚舉語法使用Switch語句匹配枚舉值關聯(lián)值原...
    寒橋閱讀 1,559評論 0 3
  • 閉包(closure)是Javascript語言的一個難點硅瞧,也是它的特色,很多高級應用都要依靠閉包實現(xiàn)恕汇。 一、變量...
    zock閱讀 1,075評論 2 6
  • 閉包(closure)是Javascript語言的一個難點,也是它的特色橄维,很多高級應用都要依靠閉包實現(xiàn)证舟。 一、變量...
    zouCode閱讀 1,271評論 0 13
  • 閉包: 官方”的解釋是:閉包是一個擁有許多變量和綁定了這些變量的環(huán)境的表達式(通常是一個函數(shù))方咆,因而這些變量也是該...
    小裁縫sun閱讀 618評論 0 5
  • 臨近十一長假的前幾天老公忽然興奮的拿著手機讓我看月腋,我不以為然的喵了一眼我眼前一亮:原來是山東省東營市的黃河口風...
    胖胖胖016_cms閱讀 240評論 0 0