JavaScript做用域相關的總結

這裏主要記錄在平常中對知識的學習,經過結合筆記與自身理解的方式嘗試寫下總結
文章對細節可能不會一一介紹解釋,內容僅做參考
複製代碼

做用域指程序源代碼中定義變量的區域,規定了如何查找變量即肯定當前執行代碼對變量的訪問權限bash

JavaScript採用的是詞法做用域,也就是函數的做用域函數定義的時候就決定
與詞法做用域相反的是動態做用域,也就是函數的做用域是在函數調用的時候才決定,這裏僅供瞭解就好函數


在JavaScript中主要有全局做用域函數做用域塊級做用域(ES6以前沒有)三個學習

  • 全局做用域:顧名思義,是爲最頂層最大的範圍
  • 函數做用域:僅在某個函數內部有效的範圍
  • 塊級做用域:僅在某個塊級代碼內部有效的範圍

做用域是一個很抽象的概念,能夠理解成一個地盤,具備spa

  • 獨立性:做用域包裹起來讓變量不會外泄,因此在不一樣做用域下同名變量不會有衝突 - 隔離變量
  • 分層與嵌套:做用域是有層級關係的,上下級關係的肯定就看函數是在哪一個做用域下定義的(在哪一個做用域下定義就是哪一個做用域的子做用域

內層做用域(子做用域)能夠訪問外層做用域(父做用域)的變量,反之則不行。在查找一個變量時,若是在本做用域內無定義,那麼就會往上一層父做用域查找,一層一層向上直到全局做用域,這種方式就成爲了做用域鏈code


再強調一次:做用域是在相應代碼定義時就被建立(例如定義函數時決定相對應的函數做用域)ip


舉個栗子加深一下理解:作用域

function foo() {
    var b = 2
    function bar(c) {
        var d = 3
        console.log(a, b, c, d)
    }
    bar(b * 3)
}
function hkk() {
    var e = 4
    console.log(a, e)
}
var a = 1
複製代碼

假設走到這段代碼的時候,最外層做用域是全局做用域,目前的做用域層級爲it

[全局做用域]
複製代碼

定義foo函數,會有一個foo做用域產生io

[全局做用域[foo做用域]]
複製代碼

而後走進foo裏面,定義bar函數,會有一個bar做用域產生console

[全局做用域 [foo做用域 [ bar做用域 ] ] ]
複製代碼

繞出來後,還定義了hkk函數,會有一個hkk做用域產生

[全局做用域 [foo做用域 [ bar做用域 ], hkk做用域]]
複製代碼

在接下來變量的查找就會依賴這個做用域鏈 好比說在上面代碼會有

  • bar -> foo -> 全局
  • hkk -> 全局

在函數執行時變量的查找就會變成這樣:

function foo() {
    var b = 2
    function bar(c) {
        var d = 3
        console.log(a, b, c, d)
        // a: 在bar這裏找不到,去foo那裏找找。foo也找不到呢,再上去全局找找。在全局找到了 -> 最後得出這個值要在全局做用域下拿到
        // b: 在bar這裏找不到,去foo那裏找找。在foo找到了 -> 最後得出這個值要在foo做用域下拿到
        // c: 在bar這裏找到了 -> 最後得出這個值要在bar做用域下拿到
        // d: 在bar這裏找到了 -> 最後得出這個值要在bar做用域下拿到
    }
    bar(b * 3)
}
function hkk() {
    var e = 4
    console.log(a, e)
    // a: 在hkk這裏找不到,上去全局找找。在全局找到了 -> 最後得出這個值要在全局做用域下拿到
    // c: 在hkk這裏找到了 -> 最後得出這個值要在hkk做用域下拿到
}
var a = 1
複製代碼

做用域是執行上下文知識的前置知識

能夠想象成: 我要辦一座學校(全局),會有多個年級(函數/塊級做用域),而後呢每一個年級裏面又有多個班級(子函數/塊級做用域),每一個班級又會有跟細的組織結構

可是呢 我這裏只是想好了怎麼安排制度(某個班級考試時,若是班級本身沒有試卷,那須要的試卷應該向對應的年級拿,年級沒有,再去找學校要),但至於運行起來後,年級有多少試卷,是否還有做業,就要看年級私底下的安排了(這個這裏先不去理解 看看就好)

相關文章
相關標籤/搜索