淺談Javascript中的作用域鏈

妙筆生花發表於2018-03-18

前言

在理解作用域鏈之前先要知道執行環境。任何函式都有一個執行環境,最外圍的是全域性執行環境,每一個環境都有自己的活動物件,活動物件裡面存在的是當前環境中的變數。

作用域鏈

當程式碼在一個環境中執行時,會建立變數物件的一個作用域鏈(scope chain)。作用域鏈裡存放的是當前環境以及外部環境的活動物件。作用域鏈的最前端的活動物件始終是當前環境的,下一級就是外部環境,再下一個活動物件來自再下一級的外部環境。當前環境活動物件裡如果沒有包含函式中使用的變數,那麼會沿著作用鏈去找下一個環境中的活動物件,直到全域性環境。這樣說可能太晦澀難懂了, 讓我們分析一段程式碼:

var a = 1
function fn1(){
  function fn2(){
    console.log(a)
  }
  function fn3(){
    var a = 4
    fn2()
  }
  var a = 2
  return fn3
}
var fn = fn1()
fn() //2
複製程式碼

執行fn1其中var a = 2已經成功定義並且a被賦值2,將fn3賦予了fn然後執行fn也就是執行fn3,在fn3中a被定義並賦值4,然後執行了fn2最終結果是2,說明了fn2是從fn1中的活動物件裡找到的a。
那我們來看一下圖:

淺談Javascript中的作用域鏈

var a = 1
function fn1(){
  function fn3(){
    var a = 4
    fn2()
  }
  var a = 2
  return fn3
}
function fn2(){
  console.log(a)
}
var fn = fn1()
fn() //1
複製程式碼

上面的程式碼最終輸出的是1.說明fn2是從全域性活動物件裡查詢到a的宣告,所以查詢順序那我們應該看宣告fn2的環境,而不是呼叫fn2的環境。 看圖:

淺談Javascript中的作用域鏈

相關文章