<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

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

          共 1754字,需瀏覽 4分鐘

           ·

          2021-09-06 18:34

          人生苦短,總需要一點儀式感。比如學前端~

          全局變量和局部變量

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

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

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

          作用域鏈

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

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

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

          當前執(zhí)行上下文 - 上一級 - 上上級 - …… - 全局上下文

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

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

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

          簡單分析上面的流程:

          全局執(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。

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

          總結:

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

          js有個內部[[scope]],這個屬性包含了函數(shù)的作用域對象的集合,這個集合就稱為函數(shù)的作用域鏈。它決定了哪些變量或者函數(shù)能在當前函數(shù)中被訪問以及它的訪問順序。

          VO 和 AO

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

          區(qū)分作用域與this

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


          END
          愿你歷盡千帆,歸來仍是少年。
          瀏覽 32
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  色婷婷AV一区二区三区之e本道 | 免费A片视频网站 | 综合五月丁香视频 | 国产成人片 | 狠狠穞A片一區二區三區 |