本系列用了大量的篇幅講解了上下文環(huán)境和作用域,有些人反映這兩個(gè)是一回兒事。本文就用一個(gè)小例子來說明一下,作用域和上下文環(huán)境絕對(duì)不是一回事兒。
再說明之前,咱們先用簡單的語言來概括一下這兩個(gè)的區(qū)別。
00 上下文環(huán)境:
可以理解為一個(gè)看不見摸不著的對(duì)象(有若干個(gè)屬性),雖然看不見摸不著,但確實(shí)實(shí)實(shí)在在存在的,因?yàn)樗械淖兞慷荚诶锩娲鎯?chǔ)著,要不然咱們定義的變量在哪里存?
另外,對(duì)于函數(shù)來說,上下文環(huán)境是在調(diào)用時(shí)創(chuàng)建的,這個(gè)很好理解。拿參數(shù)做例子,你不調(diào)用函數(shù),我哪兒知道你要給我傳什么參數(shù)?
01 作用域:
首先,它很抽象。第二,記住一句話:除了全局作用域,只有函數(shù)才能創(chuàng)建作用域。創(chuàng)建一個(gè)函數(shù)就創(chuàng)建了一個(gè)作用域,無論你調(diào)用不調(diào)用,函數(shù)只要?jiǎng)?chuàng)建了,它就有獨(dú)立的作用域,就有自己的一個(gè)“地盤”。
02 兩者:
一個(gè)作用域下可能包含若干個(gè)上下文環(huán)境。有可能從來沒有過上下文環(huán)境(函數(shù)從來就沒有被調(diào)用過);有可能有過,現(xiàn)在函數(shù)被調(diào)用完畢后,上下文環(huán)境被銷毀了;有可能同時(shí)存在一個(gè)或多個(gè)(閉包)。
上面的文字不理解沒關(guān)系,且看下面的例子。
第一,除了全局作用域外,每個(gè)函數(shù)都要?jiǎng)?chuàng)建一個(gè)作用域。作用域之間的變量是相互獨(dú)立的。因此,全局作用域中的x和fn作用域中的x,兩者毫無關(guān)系,互不影響,和平相處。
第二,程序執(zhí)行之前,會(huì)生成全局上下文環(huán)境,并在程序執(zhí)行時(shí),對(duì)其中的變量賦值。
第三,程序執(zhí)行到第17行,調(diào)用fn(5),會(huì)產(chǎn)生fn(5)的上下文環(huán)境,并壓棧,并設(shè)置為活動(dòng)狀態(tài)。
第四,執(zhí)行完第17行,fn(5)的返回值賦值給了f1。此時(shí)執(zhí)行上下文環(huán)境又重新回到全局,但是fn(5)的上下文環(huán)境不能就此銷毀,因?yàn)槠渲杏虚]包的引用(可翻看前面文章,此處不再贅述)。
第五,繼續(xù)執(zhí)行第18行,再次調(diào)用fn函數(shù)——fn(10)。產(chǎn)生fn(5)的上下文環(huán)境,并壓棧,并設(shè)置為活動(dòng)狀態(tài)。但是此時(shí)fn(5)的上下文環(huán)境還在內(nèi)存中——一個(gè)作用域下同時(shí)存在兩個(gè)上下文環(huán)境。
講到這里,重點(diǎn)已經(jīng)講出來了,之后的場景這里就不再贅述了。
目的還是希望大家能通過這個(gè)例子,來理清楚上下文環(huán)境和作用域的關(guān)系。當(dāng)然,也不是非得像個(gè)學(xué)院派似的一字一文的把概念說出來,簡單理解一下,對(duì)用閉包是有幫助的。
---------------------------------------------------------------------------
本文已更新到《深入理解javascript原型和閉包系列》的目錄,更多內(nèi)容可參見《深入理解javascript原型和閉包系列》。
另外,歡迎關(guān)注我的微博。
也歡迎關(guān)注我的其他教程:
《用grunt搭建自動(dòng)化的web前端開發(fā)環(huán)境》《從設(shè)計(jì)到模式》《json2.js源碼解讀視頻》《微軟petshop4.0源碼解讀視頻》
--------------------------------------------------------------------------
聯(lián)系客服