<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當(dāng)前位置: 首頁 - 科技 - 知識百科 - 正文

        javascript作用域鏈(ScopeChain)用法實(shí)例解析_javascript技巧

        來源:懂視網(wǎng) 責(zé)編:小采 時(shí)間:2020-11-27 21:46:32
        文檔

        javascript作用域鏈(ScopeChain)用法實(shí)例解析_javascript技巧

        javascript作用域鏈(ScopeChain)用法實(shí)例解析_javascript技巧:本文實(shí)例分析了javascript作用域鏈(Scope Chain)用法。分享給大家供大家參考,具體如下: 關(guān)于js的作用域鏈,早有耳聞,也曾看過幾篇介紹性的博文,但一直都理解的模棱兩可。近日又精心翻看了一下《悟透Javascript》這本書,覺得寫得太深刻,在代碼的時(shí)空
        推薦度:
        導(dǎo)讀javascript作用域鏈(ScopeChain)用法實(shí)例解析_javascript技巧:本文實(shí)例分析了javascript作用域鏈(Scope Chain)用法。分享給大家供大家參考,具體如下: 關(guān)于js的作用域鏈,早有耳聞,也曾看過幾篇介紹性的博文,但一直都理解的模棱兩可。近日又精心翻看了一下《悟透Javascript》這本書,覺得寫得太深刻,在代碼的時(shí)空

        本文實(shí)例分析了javascript作用域鏈(Scope Chain)用法。分享給大家供大家參考,具體如下:

        關(guān)于js的作用域鏈,早有耳聞,也曾看過幾篇介紹性的博文,但一直都理解的模棱兩可。近日又精心翻看了一下《悟透Javascript》這本書,覺得寫得太深刻,在“代碼的時(shí)空”一節(jié)里有一段介紹作用域鏈的地方寥寥數(shù)語,回味無窮(其實(shí)還是理解的模棱兩可^_^)。現(xiàn)在整理下自己的讀書筆記,順便借鑒網(wǎng)上資源,寫下來。

        一、從一個(gè)簡單的問題說起

        下面的js代碼在頁面中運(yùn)行顯示什么結(jié)果:

        您的答案是什么?沒錯(cuò),就是彈出10。我的理解是這樣的,funTest函數(shù)有一個(gè)形參arg,funTest函數(shù)傳入實(shí)參10,alert方法把10彈出就是了,囧。
        好,問題又來了:

        答案是什么?如果是5年前的我,肯定不會再往下想了,還是10!這么簡單的問題還用想什么呀?我的理解是這樣的:funTest函數(shù)是一個(gè)無參數(shù)的函數(shù),函數(shù)內(nèi)部通過alert方法,調(diào)用外部(全局)的變量arg,在函數(shù)執(zhí)行前,arg賦值為10,彈出arg值后改變arg值為2,所以彈出值為10。

        真的是10嗎?是還是不是?

        測試的結(jié)果:彈出“undefined”,瀑布汗.

        二、理解作用域鏈,從javascript運(yùn)行機(jī)制說起

        1、js的運(yùn)行順序

        如果一個(gè)文檔流中包含多個(gè)script代碼段(用script標(biāo)簽分隔的js代碼或引入的js文件),它們的運(yùn)行順序是:

        步驟1. 讀入第一個(gè)代碼段(js執(zhí)行引擎并非一行一行地執(zhí)行程序,而是一段一段地分析執(zhí)行的)
        步驟2. 做語法分析,有錯(cuò)則報(bào)語法錯(cuò)誤(比如括號不匹配等),并跳轉(zhuǎn)到步驟5
        步驟3. 對var變量和function定義做“預(yù)解析”(永遠(yuǎn)不會報(bào)錯(cuò)的,因?yàn)橹唤馕稣_的聲明)
        步驟4. 執(zhí)行代碼段,有錯(cuò)則報(bào)錯(cuò)(比如變量未定義)
        步驟5. 如果還有下一個(gè)代碼段,則讀入下一個(gè)代碼段,重復(fù)步驟2
        步驟6. 結(jié)束

        上面的分析已經(jīng)足夠清楚,步驟二、三和步驟四里的紅色字體可能是我們新手理解上的一個(gè)盲點(diǎn),尤其是步驟三的“預(yù)解析”,如果不清楚什么叫預(yù)解析,總覺得不踏實(shí)。而步驟四的“有錯(cuò)則報(bào)錯(cuò)”也是經(jīng)常碰到的。舉例來說:

        上面這段代碼執(zhí)行時(shí),彈出“undefined”,也就是說arg沒有定義,js的變量不是不用定義也可以嗎?

        2、語法分析和“預(yù)解析”

        (1)、從解釋型語言的編譯過程說起

        眾所周知,javascript是解釋型語言,它不同于c#和java等編譯型語言。對于傳統(tǒng)編譯型語言來說,編譯步驟分為:詞法分析、語法分析、語義檢查、代碼優(yōu)化和字節(jié)生成;但對于解釋型語言來說,通過詞法分析和語法分析得到語法樹后,就可以開始解釋執(zhí)行了。

        a、詞法分析

        簡單地說,詞法分析是將字符流(char stream)轉(zhuǎn)換為記號流(token stream)。
        但是這個(gè)轉(zhuǎn)換過程并不是可以用一句話就可以概括的那么簡單,我們可以試著用偽代碼理解一段簡單的程序:

        代碼var result=x-y;的轉(zhuǎn)換大致可以表示如下:

        NAME "result"
        EQUALS
        NAME "x"
        MINUS
        NAME "y"
        SEMICOLON

        b、語法分析

        簡單地說,語法分析就是為了構(gòu)造合法的語法分析樹,而語法分析樹可以直觀地表示出推導(dǎo)的過程。

        那么什么是語法分析樹?簡單地說,就是程序推導(dǎo)過程的描述。但是到底什么是語法樹,請參考專業(yè)文章,本篇略過。

        c、其他

        通過語法分析,構(gòu)造出語法分析樹后,接下來還可能需要進(jìn)一步的語義檢查。對于傳統(tǒng)強(qiáng)類型語言來說,語義檢查的主要部分是類型檢查,比如函數(shù)的實(shí)參和形參類型是否匹配等等。
        結(jié)論:通過上面的分析可以看出,對于javascript引擎來說,肯定有詞法分析和語法分析,之后可能還有語義檢查、代碼優(yōu)化等步驟,等這些編譯步驟完成之后(任何語言都有編譯過程,只是解釋型語言沒有編譯成二進(jìn)制代碼),才會開始執(zhí)行代碼。

        (2)、執(zhí)行過程

        a、javascript的作用域機(jī)制

        通過編譯,javascript代碼已經(jīng)翻譯成了語法樹,然后會立刻按照語法樹執(zhí)行。

        進(jìn)一步的執(zhí)行過程,需要理解javascript的作用域機(jī)制:詞法作用域(lexcical scope)。通俗地講,就是javascript變量的作用域是在定義時(shí)決定而不是執(zhí)行時(shí)決定,也就是說詞法作用域取決于源碼,編譯器通過靜態(tài)分析就能確定,因此詞法作用域也叫做靜態(tài)作用域(static scope)。但需要注意,with和eval的語義無法僅通過靜態(tài)技術(shù)實(shí)現(xiàn),所以只能說javascript的作用域機(jī)制非常接近詞法作用域(lexical scope).

        javascript引擎在執(zhí)行每個(gè)函數(shù)實(shí)例時(shí),都會創(chuàng)建一個(gè)執(zhí)行環(huán)境(execution context)。執(zhí)行環(huán)境中包含一個(gè)調(diào)用對象(call object), 調(diào)用對象是一個(gè)scriptObject結(jié)構(gòu)(scriptObject是與函數(shù)相關(guān)的一套靜態(tài)系統(tǒng),與函數(shù)實(shí)例的生命周期保持一致),用來保存內(nèi)部變量表varDecls、內(nèi)嵌函數(shù)表funDecls、父級引用列表upvalue等語法分析結(jié)構(gòu)(注意varDecls和funDecls等信息是在語法分析階段就已經(jīng)得到,并保存在語法樹中。函數(shù)實(shí)例執(zhí)行時(shí),會將這些信息從語法樹復(fù)制到scriptObject上)。

        b、javascript作用域機(jī)制的實(shí)現(xiàn)方法

        詞法作用域(lexical scope)是javascript的作用域機(jī)制,還需要理解它的實(shí)現(xiàn)方法,就是作用域鏈(scope chain)。作用域鏈?zhǔn)且粋€(gè)name lookup機(jī)制,首先在當(dāng)前執(zhí)行環(huán)境的scriptObject中尋找,沒找到,則順著upvalue到父scriptObject中尋找,一直lookup到全局調(diào)用對象(global object)。

        現(xiàn)在回過頭來分析第二個(gè)問題:

        在執(zhí)行funcTest函數(shù)時(shí),也即進(jìn)入了funcTest對應(yīng)的作用域,js引擎在執(zhí)行時(shí),當(dāng)遇到對變量名或者函數(shù)名的使用時(shí),會首先在當(dāng)前作用域(也即funcTest對應(yīng)的作用域)查找變量或者函數(shù)(顯然,arg變量在funcTest對應(yīng)的作用域里被定義為var arg=2 所以alert方法的參數(shù)采用的是當(dāng)前作用域的arg,但是因?yàn)閍rg被定義在alert方法后,所以arg變量默認(rèn)值為undefined)。當(dāng)然,如果沒有找到就到上層作用域查找,依此類推(作用域范圍可以持續(xù)到j(luò)avascript運(yùn)行環(huán)境的根:window對象)。

        最后,讓你看的更清楚,上面的代碼其實(shí)可以等價(jià)于:

        c、閉包(closure)

        當(dāng)一個(gè)函數(shù)實(shí)例執(zhí)行時(shí),會創(chuàng)建或關(guān)聯(lián)到一個(gè)閉包。 (關(guān)于閉包,打算另寫一篇學(xué)習(xí)筆記)

        scriptObject用來靜態(tài)保存與函數(shù)相關(guān)的變量表,閉包則在執(zhí)行期動態(tài)保存這些變量表及其運(yùn)行值;

        閉包的生命周期有可能比函數(shù)實(shí)例長。函數(shù)實(shí)例在活動引用為空后會自動銷毀;

        閉包則要等要數(shù)據(jù)引用為空后,由javascript引擎回收(有些情況下不會自動回收,就導(dǎo)致了內(nèi)存泄漏)。

        ps:關(guān)于“執(zhí)行過程”這一段比較拗口,名詞很多,不過別被它們嚇住,一旦理解了執(zhí)行環(huán)境(execution context)、調(diào)用對象(call object)、詞法作用域(lexical scope)、作用域鏈(scope chain)、閉包(closure)等這些概念,javascript的很多現(xiàn)象都能迎刃而解。

        三、結(jié)語

        通過第二段的分析,對照第一段筆者曾經(jīng)做出的判斷(你是不是也覺得筆者曾經(jīng)的分析和結(jié)論很幼稚(哪怕有時(shí)結(jié)果碰巧也對!)?!不是一般的膚淺啊,^_^),你會發(fā)現(xiàn)原來javascript還有這么多“玄機(jī)”,而要真正理解精通又談何容易?先“悟透”再說吧。

        希望本文所述對大家JavaScript程序設(shè)計(jì)有所幫助。

        聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        javascript作用域鏈(ScopeChain)用法實(shí)例解析_javascript技巧

        javascript作用域鏈(ScopeChain)用法實(shí)例解析_javascript技巧:本文實(shí)例分析了javascript作用域鏈(Scope Chain)用法。分享給大家供大家參考,具體如下: 關(guān)于js的作用域鏈,早有耳聞,也曾看過幾篇介紹性的博文,但一直都理解的模棱兩可。近日又精心翻看了一下《悟透Javascript》這本書,覺得寫得太深刻,在代碼的時(shí)空
        推薦度:
        標(biāo)簽: js 使用技巧 javascript
        • 熱門焦點(diǎn)

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 亚洲欧洲日产国码高潮αv| 久久午夜免费鲁丝片| 亚洲AV网站在线观看| 成年在线网站免费观看无广告| 亚洲视频一区调教| 99久热只有精品视频免费观看17| 久久精品国产96精品亚洲 | 国产亚洲人成网站在线观看不卡| 九九99热免费最新版| 亚洲AV无码码潮喷在线观看| 日本免费中文字幕| 亚洲一级免费毛片| 色视频色露露永久免费观看 | 在线视频精品免费| 亚洲狠狠成人综合网| 免费国产真实迷j在线观看| fc2免费人成在线| 日本免费一区二区三区最新| 亚洲国产一区国产亚洲| 久久久久久曰本AV免费免费| 亚洲人成在线播放网站| 午夜爽爽爽男女免费观看影院| 久久精品国产亚洲Aⅴ香蕉| 九九精品成人免费国产片| 亚洲精品永久www忘忧草| 黄色成人网站免费无码av| 理论片在线观看免费| 国产免费人成在线视频| 亚洲中文字幕无码爆乳app| 国产精品怡红院永久免费| 亚洲午夜无码久久| 亚洲午夜福利精品无码| 免费福利在线观看| 亚洲Av无码乱码在线znlu| 日韩免费无码视频一区二区三区 | 亚洲国产成人久久一区久久| 免费无遮挡无码永久视频| 亚洲av成本人无码网站| 久久精品国产亚洲av麻豆| 日本无吗免费一二区| 久久99热精品免费观看动漫|