JS執(zhí)行環(huán)境與作用域鏈

執(zhí)行環(huán)境

執(zhí)行環(huán)境(excecution context),也叫做執(zhí)行上下文抗楔,定義了變量或函數(shù)有權(quán)訪問的其他數(shù)據(jù)惯雳,決定了它們各自的行為。每個只i系那個環(huán)境都有一個與之關(guān)聯(lián)的變量對象妥箕,環(huán)境中定義的所有變量和函數(shù)都保存在這個對象中滥酥。
全局執(zhí)行環(huán)境是最外圍的一個執(zhí)行環(huán)境,在Web瀏覽器中畦幢,全局執(zhí)行環(huán)境被認為是window對象坎吻。
每個函數(shù)都有子句的只想能夠環(huán)境。當一個函數(shù)被調(diào)用時宇葱,函數(shù)的環(huán)境就會被推入一個環(huán)境棧中瘦真,而在函數(shù)執(zhí)行之后,棧將環(huán)境他出黍瞧,吧控制權(quán)返回給之前的執(zhí)行環(huán)境诸尽。

看下面這一段代碼

console.log(a) // Uncaught ReferenceError: a is not defined
console.log(a) // undefined
var a = 10;
console.log(a) // 10

在一段代碼執(zhí)行之前,JS就已經(jīng)做了一些“準備工作”印颤,包括對變量的聲明您机,這段代碼里所有變量的聲明都被提前到代碼一句一句執(zhí)行之前完成,但僅僅是聲明,而沒有賦值往产。變量復制是在執(zhí)行到賦值語句的時候進行的被碗。

console.log(fn1) ;  //? fn1() {}
function fn1() {}

console.log(fn2);  // undefined
var fn2 = function() {};

函數(shù)聲明和函數(shù)表達式的待遇是不同的,對于函數(shù)聲明仿村,準備階段會同時為函數(shù)名賦值锐朴,而對函數(shù)表達式,就只是聲明了蔼囊。

全局環(huán)境下的執(zhí)行環(huán)境中焚志,包括

  • 變量,函數(shù)表達式 —— 聲明畏鼓,默認值為undefined
  • this —— 賦值
  • 函數(shù)聲明 —— 賦值

每次調(diào)用一個函數(shù) 回铛,也會創(chuàng)建這個函數(shù)的執(zhí)行環(huán)境,相比于全局環(huán)境的執(zhí)行環(huán)境葫男,還多了這些:

  • 參數(shù) —— 賦值
  • arguments —— 賦值
  • 確定變量的作用域

作用域鏈

當代碼在一個環(huán)境中運行是矫渔,會創(chuàng)建變量對象的一個作用域鏈。作用域鏈的用途是让禀,保證對執(zhí)行環(huán)境有權(quán)訪問的所有變量和函數(shù)的有序訪問挑社。
在一個函數(shù)中可以訪問函數(shù)之外定義的變量,這就和作用域與作用域鏈有關(guān)

var a = 10;
function fn1() {
    console.log(a); // 10
}

function fn2() {
    var a = 20;
    fn1(); // 10巡揍,而不是20
}

函數(shù)在訪問一個變量的時候:

  1. 先從自己內(nèi)部找變量
  2. 如果找不到痛阻,再從創(chuàng)建當前函數(shù)所在的作用域去找, 以此往上
  3. 如果一直到全局作用域還沒有找到,說明變量未定義腮敌,報錯

注意要到創(chuàng)建這個函數(shù)的那個作用域中取值——是“創(chuàng)建”阱当,而不是“調(diào)用”。函數(shù)在定義的時候(不是調(diào)用的時候)糜工,就已經(jīng)確定了函數(shù)體內(nèi)部自由變量的作用域弊添。

var a = 10;

function fn() {
    var b = 20;
    function bar() {
        console.log(a + b);
    }
    return bar;
}

var x = fn(),
    b = 200;
x(); // 30

以上代碼中:第13行,fn()返回的是bar函數(shù)捌木,賦值給x油坝。執(zhí)行x(),即執(zhí)行bar函數(shù)代碼钮莲。取b的值時免钻,直接在fn作用域取出。取a的值時崔拥,試圖在fn作用域取极舔,但是取不到,只能轉(zhuǎn)向創(chuàng)建fn的那個作用域中去查找链瓦,結(jié)果找到了拆魏。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末盯桦,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子渤刃,更是在濱河造成了極大的恐慌拥峦,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件卖子,死亡現(xiàn)場離奇詭異略号,居然都是意外死亡,警方通過查閱死者的電腦和手機洋闽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門玄柠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人诫舅,你說我怎么就攤上這事羽利。” “怎么了刊懈?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵这弧,是天一觀的道長。 經(jīng)常有香客問我虚汛,道長匾浪,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任泽疆,我火速辦了婚禮户矢,結(jié)果婚禮上玲献,老公的妹妹穿的比我還像新娘殉疼。我一直安慰自己,他們只是感情好捌年,可當我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布瓢娜。 她就那樣靜靜地躺著,像睡著了一般礼预。 火紅的嫁衣襯著肌膚如雪眠砾。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天托酸,我揣著相機與錄音褒颈,去河邊找鬼。 笑死励堡,一個胖子當著我的面吹牛谷丸,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播应结,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼刨疼,長吁一口氣:“原來是場噩夢啊……” “哼泉唁!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起揩慕,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤亭畜,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后迎卤,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拴鸵,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年蜗搔,在試婚紗的時候發(fā)現(xiàn)自己被綠了宝踪。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡碍扔,死狀恐怖瘩燥,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情不同,我是刑警寧澤厉膀,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站二拐,受9級特大地震影響服鹅,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜百新,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一企软、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧饭望,春花似錦仗哨、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至斟珊,卻和暖如春苇倡,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背囤踩。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工旨椒, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人堵漱。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓综慎,卻偏偏與公主長得像,于是被迫代替她去往敵國和親怔锌。 傳聞我的和親對象是個殘疾皇子寥粹,可洞房花燭夜當晚...
    茶點故事閱讀 44,619評論 2 354

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