資源描述:
《詳解javascript上下文與作用域》由會(huì)員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在教育資源-天天文庫。
1、圖文并茂詳解Javascript上下文與作用域本文嘗試闡述Javascript中的上下文與作用域背后的機(jī)制,主要涉及到執(zhí)行上下文(executioncontext)、作用域鏈(scopechain)、閉包(closure)、this等概念。Executioncontext執(zhí)行上下文(簡稱上下文)決定了Js執(zhí)行過程中可以獲取哪些變量、函數(shù)、數(shù)據(jù),一段程序可能被分割成許多不同的上下文,每一個(gè)上下文都會(huì)綁定一個(gè)變量對(duì)象(variableobject),它就像一個(gè)容器,用來存儲(chǔ)當(dāng)前上下文中所有已定義或可獲取的變量、函數(shù)等。位于最頂端或最外層的上下文稱為全局上下文(globalcontext),全局上下
2、文取決于執(zhí)行環(huán)境,如Node中的global和Browser中的window:?需要注意的是,上下文與作用域(scope)是不同的概念。Js本身是單進(jìn)程的,每當(dāng)有function被執(zhí)行時(shí),就會(huì)產(chǎn)生一個(gè)新的上下文,這一上下文會(huì)被壓入Js的上下文堆棧(contextstack)中,function執(zhí)行結(jié)束后則被彈出,因此Js解釋器總是在棧頂上下文中執(zhí)行。在生成新的上下文時(shí),首先會(huì)綁定該上下文的變量對(duì)象,其中包括arguments和該函數(shù)中定義的變量;之后會(huì)創(chuàng)建屬于該上下文的作用域鏈(scopechain),最后將this賦予這一function所屬的Object,這一過程可以通過下圖表示:this
3、上文提到this被賦予function所屬的Object,具體來說,當(dāng)function是定義在global對(duì)中時(shí),this指向global;當(dāng)function作為Object的方法時(shí),this指向該Object:1.var?x?=?1;?2.var?f?=?function(){?3.??console.log(this.x);?4.}?5.f();??//?->?1?6.?7.var?ff?=?function(){?8.??this.x?=?2;?9.??console.log(this.x);?10.}?11.ff();?//?->?2?12.x?????//?->?2?13.?14.v
4、ar?o?=?{x:?"o's?x",?f:?f};?15.o.f();?//?"o's?x"?上文提到,在function被執(zhí)行時(shí)生成新的上下文時(shí)會(huì)先綁定當(dāng)前上下文的變量對(duì)象,再創(chuàng)建作用域鏈。我們知道function的定義是可以嵌套在其他function所創(chuàng)建的上下文中,也可以并列地定義在同一個(gè)上下文中(如global)。作用域鏈實(shí)際上就是自下而上地將所有嵌套定義的上下文所綁定的變量對(duì)象串接到一起,使嵌套的function可以“繼承”上層上下文的變量,而并列的function之間互不干擾:1.var?x?=?'global';?2.function?a(){?3.??var?x?=?"a's
5、?x";?4.??function?b(){?5.????var?y?=?"b's?y";?6.????console.log(x);?7.??};?8.??b();?9.}?10.function?c(){?11.??var?x?=?"c's?x";?12.??function?d(){?13.????console.log(y);?14.??};?15.??d();?16.}?17.a();??//?->?"a's?x"?18.c();??//?->?ReferenceError:?y?is?not?defined?19.x?????//?->?"global"?20.y?????//?-
6、>?ReferenceError:?y?is?not?defined?Closure如果理解了上文中提到的上下文與作用域鏈的機(jī)制,再來看閉包的概念就很清楚了。每個(gè)function在調(diào)用時(shí)會(huì)創(chuàng)建新的上下文及作用域鏈,而作用域鏈就是將外層(上層)上下文所綁定的變量對(duì)象逐一串連起來,使當(dāng)前function可以獲取外層上下文的變量、數(shù)據(jù)等。如果我們在function中定義新的function,同時(shí)將內(nèi)層function作為值返回,那么內(nèi)層function所包含的作用域鏈將會(huì)一起返回,即使內(nèi)層function在其他上下文中執(zhí)行,其內(nèi)部的作用域鏈仍然保持著原有的數(shù)據(jù),而當(dāng)前的上下文可能無法獲取原先外層fu
7、nction中的數(shù)據(jù),使得function內(nèi)部的作用域鏈被保護(hù)起來,從而形成“閉包”??聪旅娴睦樱?.var?x?=?100;?2.var?inc?=?function(){?3.??var?x?=?0;?4.??return?function(){?5.????console.log(x++);?6.??};?7.};?8.?9.var?inc1?=?inc();?10.var?inc2?=?