国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

由一道題圖解JavaScript的作用域

nevermind / 2821人閱讀

摘要:當(dāng)我將此題的作用域鏈畫出來之后,終于感覺作用域入門了。創(chuàng)建函數(shù)的作用域鏈,并初始化為函數(shù)的所包含的對象,即包含了的作用域鏈。

作用域

為了理解作用域,跪看了好幾篇大神的博文,終于略知一二。

1.題目

其中,看到這樣一道題(稍作修改):

 function factory() {
     var name = "laruence";
     var intro = function(){
          console.log("I am " + name);
          console.log("I am " + age + "years");
     }
     return intro;
}
 
function app(para){
     var name = para;
     var age = 20;
     var func = factory();
     func();
}
 
app("eve");

運(yùn)行結(jié)果是:

I am laruence
腳本報(bào)錯:Uncaught ReferenceError: age is not defined

雖然在不理解作用域的情況下,我也做出了正確答案。但當(dāng)我看了網(wǎng)上大神對作用域的講解后,再來看此題,越看越經(jīng)典,當(dāng)初能做對,純粹運(yùn)氣。當(dāng)我將此題的作用域鏈畫出來之后,終于感覺作用域入門了。

2.圖解作用域

(1)JS引擎在進(jìn)入一段可執(zhí)行的代碼時(shí),需要完成以下三個(gè)初始化工作:

創(chuàng)建一個(gè)全局對象(Global Object):全局對象在創(chuàng)建時(shí),將Math,String,Date,document 等常用的JS對象作為其屬性。還有另外一個(gè)屬性window,將window指向了自身,這樣就可以通過window訪問這個(gè)全局對象了。

構(gòu)建一個(gè)執(zhí)行環(huán)境棧( Execution Context Stack):當(dāng)執(zhí)行一個(gè)函數(shù)時(shí),該函數(shù)的執(zhí)行環(huán)境就會被推入執(zhí)行環(huán)境棧的頂部并獲取執(zhí)行權(quán)。當(dāng)這個(gè)函數(shù)執(zhí)行完畢,它的執(zhí)行環(huán)境又從這個(gè)棧的頂部被刪除,并把執(zhí)行權(quán)并還給之前執(zhí)行環(huán)境。

創(chuàng)建一個(gè)全局執(zhí)行環(huán)境(Execution Context)EC,并將這個(gè)全局執(zhí)行環(huán)境EC壓入執(zhí)行環(huán)境棧中。

創(chuàng)建一個(gè)與EC關(guān)聯(lián)的全局變量對象(Varibale Object) VO,并把VO指向全局對象。VO中不僅包含了全局對象的原有屬性,還包括在全局定義的變量和函數(shù)。同時(shí),在定義函數(shù)A的時(shí)候,還為 A 添加了一個(gè)內(nèi)部屬性scope,并將scope指向了VO。每個(gè)函數(shù)在定義的時(shí)候,都會創(chuàng)建一個(gè)與之關(guān)聯(lián)的scope屬性,scope總是指向定義函數(shù)時(shí)所在的環(huán)境。

(2)當(dāng)執(zhí)行進(jìn)入app("eve") 時(shí)

創(chuàng)建函數(shù)app的執(zhí)行環(huán)境EC(a):然后EC(a)推入執(zhí)行環(huán)境棧的頂部并獲取執(zhí)行權(quán)。

創(chuàng)建函數(shù)app的作用域鏈(Scope Chain):在javascript中,每個(gè)執(zhí)行環(huán)境都有自己的作用域鏈,用于標(biāo)識符解析,當(dāng)執(zhí)行環(huán)境被創(chuàng)建時(shí),它的作用域鏈就初始化為當(dāng)前運(yùn)行函數(shù)的scope所包含的對象。

創(chuàng)建一個(gè)當(dāng)前函數(shù)的活動對象(Activation Object) AO:AO中包含了函數(shù)的形參、arguments對象、this對象、以及局部變量和內(nèi)部函數(shù)的定義,然后AO會被推入作用域鏈的頂端。需要注意的是,在定義函數(shù)B的時(shí)候,JS引擎同樣也會為B添加了一個(gè)scope屬性,并將scope指向了定義函數(shù)B時(shí)所在的環(huán)境,定義函數(shù)B的環(huán)境就是A的活動對象AO, 而AO位于鏈表的前端,由于鏈表具有首尾相連的特點(diǎn),因此函數(shù)B的scope指向了A的整個(gè)作用域鏈。

(3)當(dāng)執(zhí)行進(jìn)入factory() 時(shí)

創(chuàng)建函數(shù)factory的執(zhí)行環(huán)境EC(f):然后EC(f)推入執(zhí)行環(huán)境棧的頂部并獲取執(zhí)行權(quán)。

創(chuàng)建函數(shù)factory的作用域鏈Scope Chain(f):在javascript中,每個(gè)執(zhí)行環(huán)境都有自己的作用域鏈,用于標(biāo)識符解析,當(dāng)執(zhí)行環(huán)境被創(chuàng)建時(shí),它的作用域鏈就初始化為當(dāng)前運(yùn)行函數(shù)的scope所包含的對象。

創(chuàng)建一個(gè)當(dāng)前函數(shù)的活動對象AO(f):AO中包含了函數(shù)的形參、arguments對象、this對象、以及局部變量和內(nèi)部函數(shù)的定義,然后AO(f)會被推入作用域鏈的頂端。需要注意的是,在定義函數(shù)intro的時(shí)候,JS引擎同樣也會為intro添加了一個(gè)scope屬性,并將scope指向了定義函數(shù)intro時(shí)所在的環(huán)境,定義函數(shù)intro的環(huán)境就是factory的活動對象AO(f), 而AO(f)位于鏈表的前端,由于鏈表具有首尾相連的特點(diǎn),因此函數(shù)intro的scope指向了factory的整個(gè)作用域鏈。

(4)當(dāng)執(zhí)行進(jìn)入func()時(shí)
函數(shù)factory被執(zhí)行以后,返回了intro的引用,并賦值給了變量func,執(zhí)行 func() 就相當(dāng)于執(zhí)行intro()。

創(chuàng)建函數(shù)intro的執(zhí)行環(huán)境EC(i),然后EC(i)推入執(zhí)行環(huán)境棧的頂部并獲取執(zhí)行權(quán)。 此時(shí)執(zhí)行環(huán)境棧中有三個(gè)執(zhí)行環(huán)境,分別是全局執(zhí)行環(huán)境、函數(shù)app的執(zhí)行環(huán)境和函數(shù)intro,intro的執(zhí)行環(huán)境在棧頂,全局執(zhí)行環(huán)境在棧的底部。

創(chuàng)建函數(shù)intro的作用域鏈Scope Chain(i),并初始化為函數(shù)intro的scope所包含的對象,即包含了factory的作用域鏈。

創(chuàng)建函數(shù)intro的活動對象AO(i),并將intro的arguments對象和this對象作為AO(i)的屬性。

執(zhí)行func()時(shí),它的作用域鏈為 VO(G ) <- AO(f) <- AO(i),所以

讀取name屬性時(shí),AO(i)對象上沒有name屬性,沿著作用域鏈到AO(f),讀取到了name屬性,值為"laruence";

讀取age屬性時(shí),其實(shí)你會發(fā)現(xiàn)只有AO(f)上定義了age屬性,而AO(f)又不在作用域鏈上,所以此時(shí)會報(bào)腳本錯誤Uncaught ReferenceError: age is not defined,表示age屬性未定義。這也從側(cè)面證明了我們上面的作用域鏈分析是正確的。

執(zhí)行完成,退出。

3.Javascript中的作用域

JavaScript中的函數(shù)運(yùn)行在它們被定義的作用域里,而不是它們被執(zhí)行的作用域里。

在JS中,每次調(diào)用一個(gè)函數(shù)的時(shí)候 ,就會進(jìn)入一個(gè)函數(shù)內(nèi)的作用域,當(dāng)從函數(shù)返回以后,就返回調(diào)用前的作用域。

在javascript中,每個(gè)函數(shù)都有自己的執(zhí)行環(huán)境,當(dāng)執(zhí)行一個(gè)函數(shù)時(shí),該函數(shù)的執(zhí)行環(huán)境就會被推入執(zhí)行環(huán)境棧的頂部并獲取執(zhí)行權(quán)。當(dāng)這個(gè)函數(shù)執(zhí)行完畢,它的執(zhí)行環(huán)境又從這個(gè)棧的頂部被刪除,并把執(zhí)行權(quán)并還給之前執(zhí)行環(huán)境。

每個(gè)函數(shù)在定義的時(shí)候,都會創(chuàng)建一個(gè)與之關(guān)聯(lián)的scope屬性,scope總是指向定義函數(shù)時(shí)所在的環(huán)境。

在javascript中,每個(gè)執(zhí)行環(huán)境都有自己的作用域鏈,用于標(biāo)識符解析,當(dāng)執(zhí)行環(huán)境被創(chuàng)建時(shí),它的作用域鏈就初始化為當(dāng)前運(yùn)行函數(shù)的scope所包含的對象。

有了作用域鏈, 在發(fā)生標(biāo)識符解析的時(shí)候, 就會逆向查詢當(dāng)前scope chain列表的每一個(gè)活動對象的屬性,如果找到同名的就返回。找不到,那就是這個(gè)標(biāo)識符沒有被定義。

全局對象(Global Object) , 這個(gè)對象全局只存在一份,它的屬性在任何地方都可以訪問,它的存在伴隨著應(yīng)用程序的整個(gè)生命周期。全局對象在創(chuàng)建時(shí),Math,String,Date,document 等常用的JS對象作為其屬性。

活動對象(Activation Object) AO,這里的活動對象扮演著變量對象的角色,只是在函數(shù)中的叫法不同而已(你可以認(rèn)為變量對象是一個(gè)總的概念,而活動對象是它的一個(gè)分支), AO中包含了函數(shù)的形參、arguments對象、this對象、以及局部變量和內(nèi)部函數(shù)的定義,然后AO會被推入作用域鏈的頂端。

參考文獻(xiàn)

javascript 從定義到執(zhí)行,你不知道的那些事

Javascript作用域原理

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/79009.html

相關(guān)文章

  • 一道JS面試所引發(fā)"血案",透過現(xiàn)象尋本質(zhì),再從本質(zhì)看現(xiàn)象

    摘要:一看這二逼就是周杰倫的死忠粉看看控制臺輸出,確實(shí)沒錯就是對象。從根本上來說,作用域是基于函數(shù)的,而執(zhí)行環(huán)境是基于對象的例如全局執(zhí)行環(huán)境即全局對象。全局對象全局屬性和函數(shù)可用于所有內(nèi)建的對象。全局對象只是一個(gè)對象,而不是類。 覺得本人寫的不算很爛的話,可以登錄關(guān)注一下我的GitHub博客,博客會堅(jiān)持寫下去。 今天同學(xué)去面試,做了兩道面試題,全部做錯了,發(fā)過來給我看,我一眼就看出來了,因?yàn)?..

    QiShare 評論0 收藏0
  • JavaScript 作用作用鏈學(xué)習(xí)

    摘要:作用域與作用域鏈每個(gè)函數(shù)都有自己的執(zhí)行環(huán)境。這是初步了解作用域,如想更深入了解作用域,請看下面鏈接作用域原理作用域鏈由一道題圖解的作用域或者看權(quán)威指南和高級程序設(shè)計(jì) 本文是我學(xué)習(xí)JavaScript作用域整理的筆記,如有不對,請多指出。 作用域 一個(gè)變量的作用域是程序源代碼中定義這個(gè)變量的區(qū)域。 而在ES5中只分為全局作用域和函數(shù)作用域,也就是說for,if,while等語句是不會創(chuàng)建...

    史占廣 評論0 收藏0
  • 深入理解JavaScript(二):一道來思考閉包

    摘要:中所有的事件綁定都是異步編程當(dāng)前這件事件沒有徹底完成,不再等待,繼續(xù)執(zhí)行下面的任務(wù)當(dāng)綁定事件后,不需要等待執(zhí)行,繼續(xù)執(zhí)行下一個(gè)循環(huán)任務(wù),所以當(dāng)我們點(diǎn)擊執(zhí)行方法的時(shí)候,循環(huán)早已結(jié)束即是最后。 概念 閉包就是指有權(quán)訪問另一個(gè)函數(shù)作用域中的變量的函數(shù) 點(diǎn)擊li標(biāo)簽彈出對應(yīng)數(shù)字 0 1...

    曹金海 評論0 收藏0
  • 一道引申出事件循環(huán)、letvar用法、iife、塊級作用

    摘要:和塊級作用域?qū)嶋H上為新增了塊級作用域。這表示外層代碼塊不受內(nèi)層代碼塊的影響。塊級作用域的出現(xiàn),實(shí)際上使得獲得廣泛應(yīng)用的立即執(zhí)行函數(shù)表達(dá)式不再必要了。其他騷氣方法參考阮老師并發(fā)模型與事件循環(huán) 沒有錯,這道題就是: for (var i = 0; i< 10; i++){ setTimeout(() => { console.log(i); }, 1000...

    animabear 評論0 收藏0
  • Deep in JS - 收藏集 - 掘金

    摘要:今天同學(xué)去面試,做了兩道面試題全部做錯了,發(fā)過來給道典型的面試題前端掘金在界中,開發(fā)人員的需求量一直居高不下。 排序算法 -- JavaScript 標(biāo)準(zhǔn)參考教程(alpha) - 前端 - 掘金來自《JavaScript 標(biāo)準(zhǔn)參考教程(alpha)》,by 阮一峰 目錄 冒泡排序 簡介 算法實(shí)現(xiàn) 選擇排序 簡介 算法實(shí)現(xiàn) ... 圖例詳解那道 setTimeout 與循環(huán)閉包的經(jīng)典面...

    enali 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<