1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        【每日一題】說下你對(duì)變量的作用域鏈的理解

        共 1754字,需瀏覽 4分鐘

         ·

        2021-09-06 18:34

        人生苦短,總需要一點(diǎn)儀式感。比如學(xué)前端~

        全局變量和局部變量

        “全局變量”指的是定義在所有函數(shù)之外的變量(也就是定義在全局代碼中的變量)

        “局部變量”與之相對(duì),所指的是在某個(gè)函數(shù)中定義的變量。
        其中,函數(shù)內(nèi)的代碼可以訪問自己上層函數(shù)的變量,也可以訪問全局變量,這樣就構(gòu)成了作用域鏈。

        特殊的隱式聲明一個(gè)變量(沒有使用 var 等語句就聲明的變量),該變量不管在哪個(gè)作用域里,就會(huì)被默認(rèn)為是全局變量

        作用域鏈

        JavaScript 引擎執(zhí)行一段代碼時(shí),會(huì)創(chuàng)建對(duì)應(yīng)的執(zhí)行上下文并推入到執(zhí)行棧中。

        查找一個(gè)變量的時(shí)候,會(huì)先從當(dāng)前代碼所在的上下文的環(huán)境記錄中查找,
        如果找到,直接返回這個(gè)變量的值;
        如果沒有找到,就會(huì)到上一級(jí)執(zhí)行上下文的環(huán)境記錄中查找,找不到會(huì)一直向上,直到全局上下文的環(huán)境記錄。

        這樣有多個(gè)執(zhí)行上下文的環(huán)境記錄構(gòu)成的鏈表,就叫做作用域鏈。

        當(dāng)前執(zhí)行上下文 - 上一級(jí) - 上上級(jí) - …… - 全局上下文。

        作用域鏈包含了執(zhí)行環(huán)境有權(quán)訪問的變量、函數(shù)的有序訪問。它是一個(gè)由變量對(duì)象(VO/AO)組成的單項(xiàng)鏈表,主要用來進(jìn)行變量查找。

        js 內(nèi)部有一個(gè)[[scope]]屬性,這個(gè)屬性就是指向作用域鏈的頂端

        var val = "全局變量";
        function AA(y{
          var val = "局部變量";
          function BB({
            var z = 0;
            alert(val);
          }
          BB();
        }
        AA(5);

        簡(jiǎn)單分析上面的流程:

        全局執(zhí)行環(huán)境:[[scope]] ---> VO[AA,val],只有全局VO, [[scope]]直接指向VO。

        函數(shù) AA 執(zhí)行環(huán)境:[[scope]] ---> VO[y,BB,val, VO[AA,val]],首先全局VO壓入棧底,然后函數(shù)AA VO壓入棧頂,[[scope]] 屬性指向棧頂,變量、函數(shù)搜索就從棧頂開始。

        函數(shù) BB 執(zhí)行環(huán)境:[[scope]]---> VO[z, VO[y,BB,val], VO[AA,val]],首先全局 VO 壓入棧底,然后依次 AA、BB 壓入棧,BB 處于棧頂,[[scope]]屬性直接指向 BB 的 VO。

        應(yīng)用場(chǎng)景:比如調(diào)用 BB,進(jìn)入 BB 的執(zhí)行環(huán)境,在執(zhí)行 alert 的時(shí)候,首先會(huì)去查找 val 的聲明,會(huì)先在作用域鏈的頂端查找,沒查到就會(huì)沿著作用域鏈繼續(xù)往下查找,直到查找到AA的變量對(duì)象就停止。

        總結(jié):

        函數(shù)執(zhí)行的時(shí)候,就將當(dāng)前函數(shù)的VO放在鏈表開頭,后面依次是上層函數(shù),最后是全局對(duì)象。變量查找則依次從鏈表的頂端開始。

        js有個(gè)內(nèi)部[[scope]],這個(gè)屬性包含了函數(shù)的作用域?qū)ο蟮募希@個(gè)集合就稱為函數(shù)的作用域鏈。它決定了哪些變量或者函數(shù)能在當(dāng)前函數(shù)中被訪問以及它的訪問順序。

        VO 和 AO

        VO:全局變量對(duì)象(Varibale Object) ,  指向全局對(duì)象window,包含定義的全局變量。
        AO:活動(dòng)變量對(duì)象(Activation Object),其實(shí)也是變量對(duì)象,可以理解為VO在函數(shù)中的叫法。不過他除了包含局部的變量,還包括函數(shù)內(nèi)部的形參、arguments對(duì)象、this對(duì)象等。

        區(qū)分作用域與this

        變量的作用域區(qū)別于 this指針:
        變量作用域是靜態(tài)的,在變量聲明后就確定的,也就是說變量聲明在哪里,他的作用域就是哪里(特殊一點(diǎn):沒有用關(guān)鍵詞聲明的是全局);
        this指針 則是動(dòng)態(tài)的,根據(jù)最后的調(diào)用情況判斷其指向誰,甚至根據(jù)call、apply、bind、new等影響能被手動(dòng)改變。


        END
        愿你歷盡千帆,歸來仍是少年。
        瀏覽 32
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            免费无码在线播放 | 欧美真军实干露性器电影 | 久久久天天| 爱爱网黄色a级 | 国产特黄A片AAAA毛片车振 | 9l视频自拍九色9l视频成人 | 亚洲免费观看高清完整版在线 | 免费一级a毛片免费观看欧美大片 | 成人无码视频在线免费观看 | 老熟女 码A片 |