js不得不聊--關(guān)于閉包與作用域

最近看了js高級程序,書上對于閉包的解釋是:''閉包是指有權(quán)訪問另一個函數(shù)作用域中的變量''.我覺得過于抽象,經(jīng)過一番查閱折騰,現(xiàn)在來談?wù)勎易约旱睦斫?希望對大家有所幫助.

  • 談閉包之前,還是先談?wù)勛饔糜?/strong>
    ①作用域:
    在之前的文章中就已經(jīng)提到過,作用域簡單來說就是某個變量有(起)作用的范圍;它的規(guī)則是內(nèi)層的作用域可以訪問外層的作用域,但是反過來不行
     function foo(){
        var b = "10";
    }
     console.log(b);//報錯,b is not defined

在上面的demo中,全局是訪問不到變量b的,外層無法訪問內(nèi)部變量.
②作用域鏈搜索原則:
在作用域中如果訪問(讀取|設(shè)置)某個變量,先在當(dāng)前作用域中搜索,如果找到那么就直接使用;
如果沒有找到,那么就向上一級作用域中繼續(xù)搜索,找到則使用,沒有找到就重復(fù)上面的過程,直到0級作用域鏈;

    var num = 10;
    function f1(){
        console.log(num);       //undefined 函數(shù)內(nèi)部變量提升,結(jié)果并不是10
        num = 66;
        console.log(num);               // 66
        function f2(){
            var num = 99;
            console.log(num);           // 99
        }
        var num = 1000;
        f2();
        console.log(num);            //1000
    }
    f1();
    console.log(num);               //10 只能訪問全局變量

了解完作用域的概念之后,對書上閉包的解釋相信大家也有了一定的理解了,既然外面作用域不能訪問內(nèi)部作用域的變量,那如果我們需要訪問的話,該怎么解決這個問題呢?于是,閉包就誕生了.

  • 我對于閉包的理解
    我對于閉包的理解,就是一種能提供一種間接訪問封閉空間中私有數(shù)據(jù)的方法躲查,你也可以理解為外部作用域訪問內(nèi)部作用域變量的方法.
    那么這個方法是如何實現(xiàn)的呢?
    閉包二字單純來講,所謂閉,就是指封閉,包,就是指包裹猜旬、包裝起來勾效。JavaScript中沒有塊級作用域各吨,函數(shù)是唯一一個可以創(chuàng)建作用域的對象,那么想封閉一個作用域沦寂,必須使用函數(shù)來包裹閉合学密。
function f1(){
     var num = 10;
     return function(){
         console.log(num);
     };
}
var f2=f1();
f2();// 10

上面的案例就是一個典型的閉包,外面作用域訪問了函數(shù)內(nèi)部的變量num传藏,那么這是怎么做到的呢?
代碼中我們在f1函數(shù)中return了一個函數(shù)f2腻暮,我們調(diào)用f1函數(shù)的結(jié)果為f2函數(shù),在f2函數(shù)調(diào)用時毯侦,會先創(chuàng)建一個執(zhí)行環(huán)境哭靖,以及相應(yīng)的作用域鏈,在函數(shù)執(zhí)行中侈离,為讀取和寫入變量的值试幽,就需要在作用域鏈中查找變量,對于f2函數(shù)卦碾,f1是它的外部作用域铺坞,所以自然能夠訪問f1中的變量num,不知不覺地洲胖,全局作用域就訪問了f1中變量num的值济榨。

  • 閉包和for循環(huán)
    《你不知道的JavaScript》中有這樣一個案例:
for (var i = 1; i <= 5; i++) {
    setTimeout( function timer(){
        console.log(i);
    },i*1000);
}

代碼的運行結(jié)果:每秒輸出一次,且輸出了五次6.
setTimeout是傳入了一個函數(shù)绿映,延遲一段時間把這個函數(shù)添加到隊列當(dāng)中擒滑,并不是延遲一段時間之后就執(zhí)行函數(shù)腐晾,這個函數(shù)要在所有其他函數(shù)執(zhí)行完畢之后才開始執(zhí)行,在這之前丐一,for循環(huán)早已經(jīng)執(zhí)行完畢藻糖,所以每次打印的值都是for循環(huán)的最終i值6,且每秒輸出一次库车。
在這里颖御,定時器里的函數(shù)無法獲取其作用域范圍的值(i的值),根本原因是定時器是一個異步事件凝颇,要解決這個問題,我們在函數(shù)上加上了一個立即執(zhí)行函數(shù)()();使得每一次循環(huán)的時候定時器函數(shù)立即執(zhí)行疹鳄,獲取i的打印值拧略。

for (var i = 1; i <= 5; i++) {
       setTimeout(( function timer(){
           console.log(i);//1,2,3,4,5
       })(),i*1000);
   }

當(dāng)然,Es6中使用let申明變量瘪弓,申明了塊級作用域也起到了同樣的作用垫蛆,這里我沒有深入了解,暫不解析腺怯。

for (let i = 1; i <= 5; i++) {
    setTimeout( function timer(){
        console.log(i);//1,2,3,4,5
    },i*1000);
}

好了袱饭,就寫這么些,希望大家看了能夠有所收獲呛占,不足之處也歡迎指正虑乖,O(∩_∩)O謝謝!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末晾虑,一起剝皮案震驚了整個濱河市疹味,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌帜篇,老刑警劉巖糙捺,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異笙隙,居然都是意外死亡洪灯,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進(jìn)店門竟痰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來签钩,“玉大人,你說我怎么就攤上這事凯亮”呔剩” “怎么了?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵假消,是天一觀的道長柠并。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么臼予? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任鸣戴,我火速辦了婚禮,結(jié)果婚禮上粘拾,老公的妹妹穿的比我還像新娘窄锅。我一直安慰自己,他們只是感情好缰雇,可當(dāng)我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布入偷。 她就那樣靜靜地躺著,像睡著了一般械哟。 火紅的嫁衣襯著肌膚如雪疏之。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天暇咆,我揣著相機(jī)與錄音锋爪,去河邊找鬼。 笑死爸业,一個胖子當(dāng)著我的面吹牛其骄,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播扯旷,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼拯爽,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了薄霜?” 一聲冷哼從身側(cè)響起某抓,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎惰瓜,沒想到半個月后否副,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡崎坊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年备禀,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片奈揍。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡曲尸,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出男翰,到底是詐尸還是另有隱情另患,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布蛾绎,位于F島的核電站昆箕,受9級特大地震影響鸦列,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜鹏倘,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一薯嗤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧纤泵,春花似錦骆姐、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至公荧,卻和暖如春归园,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背稚矿。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留捻浦,地道東北人晤揣。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像朱灿,于是被迫代替她去往敵國和親昧识。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,077評論 2 355

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

  • ● 閉包基礎(chǔ) ● 閉包作用 ● 閉包經(jīng)典例子 ● 閉包應(yīng)用 ● 閉包缺點 ● 參考資料 1盗扒、閉包基礎(chǔ) 作用域和作...
    lzyuan閱讀 938評論 0 0
  • JS 函數(shù) 函數(shù)分為兩類具名函數(shù)凡怎、匿名函數(shù)校焦,其變型可以包括自執(zhí)行函數(shù)、遞歸函數(shù) 具名函數(shù)含有名字的函數(shù)functi...
    月光在心中閱讀 976評論 0 10
  • 一耸成、執(zhí)行環(huán)境 所有變量(包括基本類型和引用類型)都存在一個執(zhí)行環(huán)境(作用域)當(dāng)中报亩,這個執(zhí)行環(huán)境決定了變量的生命周期...
    張延偉閱讀 452評論 1 1
  • 閉包(closure)是Javascript語言的一個難點,也是它的特色墓猎,很多高級應(yīng)用都要依靠閉包實現(xiàn)捆昏。 一、變量...
    zock閱讀 1,075評論 2 6
  • 這場會戰(zhàn)最終以中國失敗而告終毙沾,但我相信骗卜,這個結(jié)果是當(dāng)時那個年代的政客和將軍們,事先早以預(yù)料的左胞,一點也不會感到意外寇仓,...
    梁宵閱讀 1,622評論 2 6