函數(shù)作用域以及某些獨(dú)特的塊作用域

某個(gè)執(zhí)行環(huán)境中的所有代碼執(zhí)行完畢后,該環(huán)境被銷毀怖亭,保存在其中的所有變量和函數(shù)定義也誰(shuí)之銷毀(全局執(zhí)行環(huán)境直到應(yīng)用程序退出——例如關(guān)閉網(wǎng)頁(yè)或者瀏覽器時(shí)才會(huì)銷毀侥蒙。

通過(guò)之前的學(xué)習(xí)崔兴,我們知道通過(guò)函數(shù)作用域我們可以將內(nèi)部的變量給隱藏起來(lái)五督,此時(shí)會(huì)使得外部作用域無(wú)法訪問(wèn)包裝函數(shù)內(nèi)部的任何內(nèi)容藏否。但是使用這種技術(shù)來(lái)隱藏作用域也帶來(lái)了一些問(wèn)題:首先,函數(shù)名也污染了所處的作用域概荷;其次秕岛,必須每次顯式調(diào)用函數(shù)碌燕。

而我們所期望看到的是這樣的:函數(shù)不需要函數(shù)名(跟確切的說(shuō)是函數(shù)名不會(huì)污染所在作用域)误证;能夠自動(dòng)運(yùn)行。值得慶幸的是修壕,JavaScript提供了方法以實(shí)現(xiàn)上述兩個(gè)目標(biāo):立執(zhí)行函數(shù)表達(dá)式(IIFE)愈捅。

先不討論立執(zhí)行函數(shù)表達(dá)式的細(xì)節(jié),這里我們先討論一下弄清函數(shù)表達(dá)式和函數(shù)聲明的重要性慈鸠。我們知道函數(shù)聲明可以聲明提升蓝谨,函數(shù)聲明必須使用具名函數(shù)。那么問(wèn)題來(lái)了青团,怎么區(qū)分函數(shù)聲明和函數(shù)表達(dá)式呢譬巫?答案就是:看function關(guān)鍵字出現(xiàn)在整個(gè)聲明中的位置,如果function是出現(xiàn)在整個(gè)聲明中的第一個(gè)詞的話督笆,那么他就是一個(gè)函數(shù)聲明芦昔,否則就是一個(gè)函數(shù)表達(dá)式。

匿名函數(shù)和具名那個(gè)函數(shù)相比較的缺點(diǎn):1.棧追蹤時(shí)沒(méi)有有意義的函數(shù)名娃肿,使得調(diào)試?yán)щy咕缎;2.忽略了可讀性珠十。所以,我們需要記住的時(shí):始終給函數(shù)表達(dá)式命名是一個(gè)最佳實(shí)踐凭豪。所以說(shuō)焙蹭,使用具名函數(shù)的立執(zhí)行函數(shù)也是更加值得推廣。像下面這樣:

var a = 2;
(function IIFE(){var a = 2; console.log(a);})();//3
console.log(a);//2

將IIFE用于UMD嫂伞。

var a = 2;
(function IIFE(def){def(window);})(function def(global){
  var a = 3;
  console.log(a);
  console.log(global.a);
});

1.塊作用域
JavaScript中并不存在什么塊作用域孔厉,所以像下面這樣的語(yǔ)言結(jié)構(gòu)盡管在其他語(yǔ)言里面代表了塊作用域,但是在JavaScript中他什么都不是帖努。比方說(shuō):

for(var i = 0; i < 10; i++){
  console.log(i);
}

需要指出來(lái)的是烟馅,這里的變量i并不是在for塊中生存的。更進(jìn)一步說(shuō)明的話然磷,如果這個(gè)for是在全局作用域被調(diào)用的話郑趁,那么變量i就屬于全局作用域。WTF

var foo = true
if(foo){
  var bar = foo * 2
  bar = fun(bar)
  console.log(bar)
}

上面的bar聲明簡(jiǎn)直就是莫名其妙對(duì)吧姿搜,明明沒(méi)有塊作用域寡润,卻一本正經(jīng)的在一個(gè)塊中聲明變量,用這種寫法很容易使我們產(chǎn)生誤解舅柜。所以必須謹(jǐn)記的是:除了某些特殊情況之外梭纹,并不存在什么塊作用域。

當(dāng)然致份,如果你細(xì)究JavaScript的話变抽,那么還是會(huì)發(fā)現(xiàn)存在某些特殊的塊作用域的〉椋總結(jié)來(lái)說(shuō)绍载,也就下面這幾種場(chǎng)合之下:

  • try/catch的catch塊
  • let
  • const

try/catch中的catch塊
try/catch中的catch塊會(huì)創(chuàng)建一個(gè)塊作用域,其中聲明的變量?jī)H在catch塊中有效:

try{
  undefined()//TypeError
}catch(err){
  console.log(err)
}
console.log(err)//ReferenceError

從上面的例子滔蝉,我們可以看出在catch塊中聲明的err變量?jī)H在catch代碼塊中能被訪問(wèn)的到击儡,在外界訪問(wèn)的話直接就reference error了,所以說(shuō)catch代碼塊可以形成一個(gè)塊作用域蝠引。

let和const
在ES6中新引入的let和const關(guān)鍵字所定義的變量?jī)H存在定義位置所在的那個(gè)代碼塊阳谍,所以說(shuō)這個(gè)時(shí)候也形成了一個(gè)塊作用域。舉個(gè)例子:

var foo = true
if(foo){
  let bar = foo * 2
  bar = fun(bar)
  console.log(bar)
}
console.log(bar)//referenceerror

利用let和const定義變量的時(shí)候螃概,均不會(huì)使得變量進(jìn)行聲明提升矫夯。看個(gè)例子:

{
  console.log(bar)//referenceerror
  let bar = 2
}
{
  console.log(baz)//undefined
  var baz = 2
}

關(guān)于作用域問(wèn)題的總結(jié),除了某些特殊的情況之外是不存在塊作用域的吊洼。這些特殊情況分別是:try/catch训貌,let,const融蹂。

END

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末旺订,一起剝皮案震驚了整個(gè)濱河市弄企,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌区拳,老刑警劉巖拘领,帶你破解...
    沈念sama閱讀 218,284評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異樱调,居然都是意外死亡约素,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門笆凌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)圣猎,“玉大人,你說(shuō)我怎么就攤上這事乞而∷突冢” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 164,614評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵爪模,是天一觀的道長(zhǎng)欠啤。 經(jīng)常有香客問(wèn)我,道長(zhǎng)屋灌,這世上最難降的妖魔是什么洁段? 我笑而不...
    開(kāi)封第一講書人閱讀 58,671評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮共郭,結(jié)果婚禮上祠丝,老公的妹妹穿的比我還像新娘。我一直安慰自己除嘹,他們只是感情好写半,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著憾赁,像睡著了一般污朽。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上龙考,一...
    開(kāi)封第一講書人閱讀 51,562評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音矾睦,去河邊找鬼晦款。 笑死,一個(gè)胖子當(dāng)著我的面吹牛枚冗,可吹牛的內(nèi)容都是我干的缓溅。 我是一名探鬼主播,決...
    沈念sama閱讀 40,309評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼赁温,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼坛怪!你這毒婦竟也來(lái)了淤齐?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,223評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤袜匿,失蹤者是張志新(化名)和其女友劉穎更啄,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體居灯,經(jīng)...
    沈念sama閱讀 45,668評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡祭务,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了怪嫌。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片义锥。...
    茶點(diǎn)故事閱讀 39,981評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖岩灭,靈堂內(nèi)的尸體忽然破棺而出拌倍,到底是詐尸還是另有隱情,我是刑警寧澤噪径,帶...
    沈念sama閱讀 35,705評(píng)論 5 347
  • 正文 年R本政府宣布贰拿,位于F島的核電站,受9級(jí)特大地震影響熄云,放射性物質(zhì)發(fā)生泄漏膨更。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評(píng)論 3 330
  • 文/蒙蒙 一缴允、第九天 我趴在偏房一處隱蔽的房頂上張望荚守。 院中可真熱鬧,春花似錦练般、人聲如沸矗漾。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,904評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)敞贡。三九已至,卻和暖如春摄职,著一層夾襖步出監(jiān)牢的瞬間誊役,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,023評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工谷市, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蛔垢,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,146評(píng)論 3 370
  • 正文 我出身青樓迫悠,卻偏偏與公主長(zhǎng)得像鹏漆,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評(píng)論 2 355

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