国产99久久精品_欧美日本韩国一区二区_激情小说综合网_欧美一级二级视频_午夜av电影_日本久久精品视频

最新文章專題視頻專題問答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
當前位置: 首頁 - 科技 - 知識百科 - 正文

javascript作用域底層作用分析

來源:懂視網(wǎng) 責編:小采 時間:2020-11-27 19:46:52
文檔

javascript作用域底層作用分析

javascript作用域底層作用分析:這次給大家?guī)韏avascript作用域底層作用分析,javascript作用域底層使用的注意事項有哪些,下面就是實戰(zhàn)案例,一起來看一下。標簽: javascript什么是作用域(Scope)?作用域產(chǎn)生于程序源代碼中定義變量的區(qū)域,在程序編碼階段就確定了。javascrip
推薦度:
導讀javascript作用域底層作用分析:這次給大家?guī)韏avascript作用域底層作用分析,javascript作用域底層使用的注意事項有哪些,下面就是實戰(zhàn)案例,一起來看一下。標簽: javascript什么是作用域(Scope)?作用域產(chǎn)生于程序源代碼中定義變量的區(qū)域,在程序編碼階段就確定了。javascrip

變量的訪問規(guī)則:

  • 如果變量 a 在函數(shù)內(nèi)部定義, 則函數(shù)內(nèi)部其他變量具有訪問變量 a 的權(quán)限,但是函數(shù)外部代碼沒有訪問變量 a 的權(quán)限。所以同一作用域內(nèi)變量可以相互訪問,即 a、b、c 在同一個作用域他們就可以相互訪問。這就像雞媽媽有寶寶,雞寶寶可以相互打鬧,其他雞就不能跟他們打鬧了,為什么? 因為雞媽媽不容許~ o(^?^)o 。

  • let a = 1
    function foo () {
     let b = 1 + a
     let c = 2
     console.log(b) // 2
    }
    console.log(c) // error 全局作用無法訪問到 c
    foo()
  • 如果變量 a 在全局作用域下定義(window/global),則全局作用域下的局部作用域內(nèi)的執(zhí)行代碼或者說是表達式都可以訪問到變量 a 的值。局部變量里的同名變量(a)會截斷對全局變量 a 的訪問。(這里的變量 a 就相當于是飼養(yǎng)員,候飼養(yǎng)員會在合適的時候給雞兒們投食。但是農(nóng)場主為了節(jié)約成本,規(guī)定飼養(yǎng)員要就近給雞投食,當飼養(yǎng)員1離雞寶寶更近時其他飼養(yǎng)員就不能千里迢迢跨過鴨綠江去喂雞了。)

  • let a = 1
    let b = 2
    function foo () {
     let b = 3
     function too () {
     console.log(a) // 1
     console.log(b) // 3
     }
     too()
    }
    foo()

    再次強調(diào) javascript 作用域會嚴格限制變量的可訪問范圍: 即根據(jù)源代碼中代碼和塊的位置,被嵌套作用域擁有對嵌套作用域的訪問權(quán)限。(這一條規(guī)則說明整個農(nóng)場是有規(guī)則的,不能反向的投食。)

    作用域鏈 Scope Chain

    作用域鏈,是由當前環(huán)境與上層環(huán)境的一系列作用域共同組成,它保證了當前執(zhí)行環(huán)境對符合訪問權(quán)限的變量和函數(shù)的有序訪問。

    上面解釋的稍微有些晦澀,對于我這樣大腦不好使的就需要在大腦里重復的'讀'幾次才能明白。那么作用域鏈是干嘛的? 簡單的說作用域鏈就是解析標識符的,負責返回表達式執(zhí)行時所依賴變量的值。再簡單點回答:作用域鏈就是用來查找變量的,作用域鏈是由一系列作用域串聯(lián)起來的。

    在函數(shù)執(zhí)行過程中,每遇到一個變量,都會經(jīng)歷一次標識符解析過程以決定從哪里獲取和存儲數(shù)據(jù)。該過程從作用域鏈頭部,也就是當前執(zhí)行函數(shù)的作用域開始(下圖中從左向右),查找同名的標識符,如果找到了就返回這個標識符對應(yīng)的值,如果沒找到繼續(xù)搜索作用域鏈中的下一個作用域,如果搜索完所有作用域都未找到,則認為該標識符未定義。函數(shù)執(zhí)行過程中,每個標識符值得解析都要經(jīng)歷這樣的搜索過程。

    圖片描述

    為了具象化分析問題,我們可以假設(shè)作用域鏈是一個數(shù)組(Scope Array),數(shù)組成員有一系列變量對象組成。我們可以在數(shù)組這個單向通道中,也就是上圖模擬從左向右查詢變量對象中的標識符,這樣就可以訪問到上一層作用域中的變量了。直到最頂層(全局作用域),并且一旦找到,即停止查找。所以內(nèi)層的變量可以屏蔽外層的同名變量。想想一下如果變量不是按從內(nèi)向外的查找,那整個語言設(shè)計會變得N復雜了(我們需要設(shè)計一套復雜的雞寶寶找食物的規(guī)則)

    還是上面的栗子:

    let a = 1
    let b = 2
    function foo () {
     let b = 3
     function too () {
     console.log(a) // 1
     console.log(b) // 3
     }
     too()
    }
    foo()

    作用域嵌套結(jié)構(gòu)是這樣的:

    圖片描述

    栗子中,當 javascript 引擎執(zhí)行到函數(shù) too 時, 全局、函數(shù) foo、函數(shù) too 的上下文分別會被創(chuàng)建。上下文內(nèi)包含它們各自的變量對象和作用域鏈(注意: 作用域鏈包含可訪問到的上層作用域的變量對象,在上下文創(chuàng)建階段根據(jù)作用域規(guī)則被收集起來形成一個可訪問鏈),我們設(shè)定他們的變量對象分別為VO(global),VO(foo), VO(too)。而 too 的作用域鏈,則同時包含了這三個變量對象,所以 too 的執(zhí)行上下文可如下表示:

    too = {
     VO: {...}, // 變量對象
     scopeChain: [VO(too), VO(foo), VO(global)], // 作用域鏈
    }

    我們可以直接用scopeChain來表示作用域鏈數(shù)組,數(shù)組的第一項scopeChain[0]為作用域鏈的最前端(當前函數(shù)的變量對象),而數(shù)組的最后一項,為作用域鏈的最末端(全局變量對象 window )。所有作用域鏈的最末端都為全局變量對象。

    再舉個栗子:

    let a = 1
    function foo() {
     console.log(a)
    }
    function too() {
     let a = 2
     foo()
    }
    too() // 1

    這個栗子如果對作用域的特點理解不透徹很容易以為輸出是2。但其實最終輸出的是 1。 foo() 在執(zhí)行的時候先在當前作用域內(nèi)查找變量 a 。然后根據(jù)函數(shù)定義時的作用域關(guān)系會在當前作用域的上層作用域里查找變量標識符 a,所以最后查到的是全局作用域的 a 而不是 foo函數(shù)里面的 a 。

    變量對象、執(zhí)行上下文會在后面介紹。

    閉包

    在 JavaScript 中,函數(shù)和函數(shù)聲明時的詞法作用域形成閉包。我們來看個閉包的例子

    let a = 1
    function foo() {
     let a = 2
     function too() {
     console.log(a)
     }
     return too
    }
    foo()() // 2

    這是一個閉包的栗子,一個函數(shù)執(zhí)行后返回另一個可執(zhí)行函數(shù),被返回的函數(shù)保留有對它定義時外層函數(shù)作用域的訪問權(quán)。foo()() 調(diào)用時依次執(zhí)行了 foo、too 函數(shù)。too 雖然是在全局作用域里執(zhí)行的,但是too定義在 foo 作用域里面,根據(jù)作用域鏈規(guī)則取最近的嵌套作用域的屬性 a = 2。

    再拿農(nóng)場的故事做比如。農(nóng)場主發(fā)現(xiàn)還有一種方法會更節(jié)約成本,就是讓每個雞媽媽作為家庭成員的‘飼養(yǎng)員’, 從而改變了之前的‘飼養(yǎng)結(jié)構(gòu)’。

    關(guān)于閉包會在后面的章節(jié)里也會有介紹。

    從作用域鏈的結(jié)構(gòu)可以發(fā)現(xiàn),javascript引擎在查找變量標識符時是依據(jù)作用域鏈依次向上查找的。當標識符所在的作用域位于作用域鏈的更深的位置,讀寫的時候相對就慢一些。所以在編寫代碼的時候應(yīng)盡量少使用全局代碼,盡可能的將全局的變量緩存在局部作用域中。

    不加強記憶很容記錯作用域與后面將要介紹的執(zhí)行上下文的區(qū)別。代碼的執(zhí)行過程分為編譯階段和解釋執(zhí)行階段。始終應(yīng)該記住javascript作用域在源代碼的編碼階段就確定了,而作用域鏈是在編譯階段被收集到執(zhí)行上下文的變量對象里的。所以作用域、作用域鏈都是在當前運行環(huán)境內(nèi)代碼執(zhí)行前就確定了。這里暫且不過多的展開執(zhí)行上下文的概念,可以關(guān)注后續(xù)文章。

    相信看了本文案例你已經(jīng)掌握了方法,更多精彩請關(guān)注Gxl網(wǎng)其它相關(guān)文章!

    推薦閱讀:

    PromiseA+的實現(xiàn)步驟詳解

    EasyCanvas繪圖庫在Pixeler項目開發(fā)中使用實戰(zhàn)總結(jié)

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

    文檔

    javascript作用域底層作用分析

    javascript作用域底層作用分析:這次給大家?guī)韏avascript作用域底層作用分析,javascript作用域底層使用的注意事項有哪些,下面就是實戰(zhàn)案例,一起來看一下。標簽: javascript什么是作用域(Scope)?作用域產(chǎn)生于程序源代碼中定義變量的區(qū)域,在程序編碼階段就確定了。javascrip
    推薦度:
    標簽: 作用 js 解析
    • 熱門焦點

    最新推薦

    猜你喜歡

    熱門推薦

    專題
    Top
    主站蜘蛛池模板: 国产淫语打电话对白在线播放 | 在线观看亚洲一区 | 国产网站精品 | 91精品国产亚一区二区三区 | 97一级毛片全部免费播放 | 欧美激情综合 | 久久国产综合精品欧美 | 精品成人一区二区 | 久久久久久国产a免费观看黄色大片 | 国产欧美综合在线观看第七页 | 先锋影音制服丝袜 | 精品日韩一区二区 | 欧美高清视频在线观看 | 日韩精品成人 | 亚洲欧洲日韩 | 久久国产热 | 销魂美女一区二区 | 国产精品久久久久免费 | 欧美啊v在线观看 | 国产第一页在线播放 | 国产日产高清欧美一区二区三区 | 欧美日韩成人在线视频 | 99国产精品久久久久久久成人热 | 在线欧美精品二区三区 | 中文字幕美日韩在线高清 | 一区在线免费观看 | 亚洲视频大全 | 免费国产线观看免费观看 | 久久国产一级毛片一区二区 | 日韩第一页在线 | 国产高清免费视频 | 爆操欧美| 日韩啪 | 国产精品免费观看视频 | 91精品国产综合久久久久久 | 激情另类国内一区二区视频 | 91一区二区在线观看精品 | 欧美在线综合 | 精品国产综合成人亚洲区 | 久久久久国产一级毛片高清版 | 97一区二区三区四区久久 |