作用域作用域鏈詳解與常見考題

作用域作用域鏈

[[scopel]:

每個javascript函數都是一個對象, 對象中有些屬性我們可以訪問,但有些不可以,這些屬性僅供javascript引擎存取,[[scopel]就是其中一 個。
[[scope]]指的就是我們所說的作用域,其中存儲了運行期上下文的集合。

作用域鏈:

[[scope]]中 所存儲的執行期上下文對象的集合,這個集合呈鏈式鏈接,我們把這種鏈式鏈接叫做作用域鏈。

運行期上下文:AO

當函數執行時,會創建一個稱爲執行期上下文的內部對象。一個執行期上下文定義了一個函數執行時的環境,函數每次執行時對應的執行上下文都是獨一無二的,所以多次調用一個函數會導致創建多個執行上下文,當函數執行完畢,執行上下文被銷燬。

查找變量:從作用域鏈的頂端依次向下查找。

我們來舉例討論一下吧

function a() {
  function b() {
    var b = 234;
  }
  var a = 123;
  b();
}
var glob = 100;
a();

  1. 在a函數定義的時候:
    a 會產生一個作用域 [[scopel],裏面存的是a定義的時候的執行期上下文(全局的執行期上下文GO)如圖
    a函數被定義時,發生的過程

  2. a執行的時候(執行的前一刻)a產生一個AO,把自己AO放在作用域鏈的最頂端,形成一個新的作用域鏈
    a函數被執行的時候發生的過程

  3. a的執行產生了b的定義,b的定義的過程中會有一個 [[scopel],這個 [[scopel],就是a的作用域鏈
    b被創建的時候

  4. b執行的時候會創建一個自己的執行期上下文,把他放到作用域鏈的最頂端
    b執行的時候

a作用域鏈裏面的AO跟b作用域鏈裏面的AO是不是一樣呢
我們看看這個例子

function a(){
  function b() {
    var bb = 234;
    aa=0;
  }
  var aa = 123;
  b();
  console.log(aa) ;
}
var glob = 100;
a();

這個時候答應的aa等於什麼呢,
諾,看看結果吧
答應結果
a作用域鏈裏面的AO跟b作用域鏈裏面的AO就是一樣
我們在任何一個函數中找他的作用域鏈的時候,只需要找他的作用域鏈

tip:>(免費獲取最新完整前端課程關注vx公衆號:前端拓路者coder,回覆:資料
如果這個文章對你有用的話,歡迎點贊轉發關注,讓更多的小夥伴看到呀,畢竟分享是一個程序員最基本的美德!!!
如果有不對的請大佬指教)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章