var a=2;
var func=(function(){
var a=3;
return function(){
a++;
alert(a);
}
})();
func();
func();
經(jīng)運(yùn)行分別是4,5 為什么不全是4呢這個題是典型的考查JS的代碼執(zhí)行原理,其執(zhí)行過程解析如下:
1、當(dāng)JS引擎遇到上面的這段代碼時,會創(chuàng)建一個全局執(zhí)行上下文(一個執(zhí)行上下文的生命周期包含兩個階段,即創(chuàng)建階段和執(zhí)行階段);
2、創(chuàng)建階段,JS引擎會做如下工作:
a,創(chuàng)建變量對象(Variable Object -> VO),注:全局執(zhí)行上下文和函數(shù)執(zhí)行上下文有一點(diǎn)區(qū)別的,全局是沒有arguments的相關(guān)操作
a-1、查找function函數(shù)聲明,在VO上添加一個屬性,屬性名為函數(shù)名,屬性值為函數(shù)在內(nèi)存中的引用,遇
同名覆蓋
a-2、查找var變量聲明,在VO上添加一個屬性,屬性名是變量名,屬性值為undefined,遇同名跳過
這一步完成后的結(jié)果如下:
VO = {
a:undefined,
func:undefined
}
b,建立作用域鏈
作用域鏈其實(shí)就是一個數(shù)組,在數(shù)組的頂端存放的永遠(yuǎn)是當(dāng)前執(zhí)行上下文的VO對象,在全局執(zhí)行上下文中,作
用域鏈中只有一個全局的VO,即 [Global_Context.VO],此時JS引擎還做做一件事情,給當(dāng)前執(zhí)行上下文中函數(shù)添加個內(nèi)部屬性[[scope]](我們不能使用,僅供JS引擎使用)
比如:fn.[[scope]] = [Global_Context.VO]
c,確定this指向
這里this->window
一個執(zhí)行上下文創(chuàng)建完成后壓入棧
3、執(zhí)行階段,該階段主要完成變量賦值、函數(shù)調(diào)用等等操作,此時 VO(用戶不可操作) -> AO(用戶可操作)(注:VO/AO是同一個對象,不同階段的不同叫法)
首先遇到 a = 2;JS引擎會去當(dāng)前執(zhí)行上下文的作用域鏈中查找(查找的過程是從第一個AO對象開始,依次查找,如果找到,則返回;否則繼續(xù)查找,直到全局的AO,如果還找不到,則報錯。)
這一步完成后的結(jié)果是如下:
AO={
a:2,
/*
注:由于func表達(dá)式后面是一個自執(zhí)行匿名函數(shù),所以func的值最終是自執(zhí)行匿名函數(shù)執(zhí)行后的結(jié)果,
這個自執(zhí)行匿名函數(shù)執(zhí)行時,也會創(chuàng)建對應(yīng)的執(zhí)行上下文,和上面的過程一樣的,有自己的AO、作用域鏈
這里的作用域鏈?zhǔn)怯僧?dāng)前執(zhí)行上下文的VO和函數(shù)的內(nèi)部屬性[[scope]]組合而成,則function(){ a++;alert(a); }此函數(shù)
也有內(nèi)部屬性[[scope]]指向父級執(zhí)行上下文的作用域鏈,由于function(){ a++;alert(a); }被外部變量引用著,而該函數(shù)
的[[scope]]有指向自執(zhí)行匿名函數(shù)的作用域鏈,所以當(dāng)自執(zhí)行匿名函數(shù)執(zhí)行完畢后,執(zhí)行上下文彈出棧,但不會被銷毀,而是
又保存到內(nèi)存中其他位置。
*/
func:function(){
a++;
alert(a);
}
}
作用域鏈 [AO,Global_Context.VO]
4、第一次執(zhí)行func()時,首先會在func的執(zhí)行上下文的AO中查找a,沒有找到,就繼續(xù)到父級執(zhí)行上下文的AO中找,找到a是3,然后+1,得4
5、第二次執(zhí)行func時,同樣的執(zhí)行過程,首先會在func的執(zhí)行上下文的AO中查找a,沒有找到,就繼續(xù)到父級執(zhí)行上下文的AO中找,找到a是4,然后+1,得5
上述執(zhí)行過程涵蓋了變量提升、作用域、作用域鏈、閉包(插一個題外話:為什么閉包可以外部訪問內(nèi)部變量,很多人都知道可以訪問,但是為什么能訪問? 上面已經(jīng)給出解釋)
以上是本人對JS的底層執(zhí)行原理的大體認(rèn)識,尚有細(xì)枝末節(jié)未涉及,不足之處難免,僅供參閱。
北大青鳥APTECH成立于1999年。依托北京大學(xué)優(yōu)質(zhì)雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國IT技能型緊缺人才,是大數(shù)據(jù)專業(yè)的國家
達(dá)內(nèi)教育集團(tuán)成立于2002年,是一家由留學(xué)海歸創(chuàng)辦的高端職業(yè)教育培訓(xùn)機(jī)構(gòu),是中國一站式人才培養(yǎng)平臺、一站式人才輸送平臺。2014年4月3日在美國成功上市,融資1
北大課工場是北京大學(xué)校辦產(chǎn)業(yè)為響應(yīng)國家深化產(chǎn)教融合/校企合作的政策,積極推進(jìn)“中國制造2025”,實(shí)現(xiàn)中華民族偉大復(fù)興的升級產(chǎn)業(yè)鏈。利用北京大學(xué)優(yōu)質(zhì)教育資源及背
博為峰,中國職業(yè)人才培訓(xùn)領(lǐng)域的先行者
曾工作于聯(lián)想擔(dān)任系統(tǒng)開發(fā)工程師,曾在博彥科技股份有限公司擔(dān)任項目經(jīng)理從事移動互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍(lán)懿科技有限責(zé)任公司從事總經(jīng)理職務(wù)負(fù)責(zé)iOS教學(xué)及管理工作。
浪潮集團(tuán)項目經(jīng)理。精通Java與.NET 技術(shù), 熟練的跨平臺面向?qū)ο箝_發(fā)經(jīng)驗,技術(shù)功底深厚。 授課風(fēng)格 授課風(fēng)格清新自然、條理清晰、主次分明、重點(diǎn)難點(diǎn)突出、引人入勝。
精通HTML5和CSS3;Javascript及主流js庫,具有快速界面開發(fā)的能力,對瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁制作和網(wǎng)頁游戲開發(fā)。
具有10 年的Java 企業(yè)應(yīng)用開發(fā)經(jīng)驗。曾經(jīng)歷任德國Software AG 技術(shù)顧問,美國Dachieve 系統(tǒng)架構(gòu)師,美國AngelEngineers Inc. 系統(tǒng)架構(gòu)師。