這裏主要記錄在平常中對知識的學習,經過結合筆記與自身理解的方式嘗試寫下總結
文章對細節可能不會一一介紹解釋,內容僅做參考
複製代碼
做用域指程序源代碼中定義變量的區域,規定了如何查找變量即肯定當前執行代碼對變量的訪問權限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做用域]]
複製代碼
在接下來變量的查找就會依賴這個做用域鏈 好比說在上面代碼會有
在函數執行時變量的查找就會變成這樣:
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
複製代碼
做用域是執行上下文知識的前置知識
能夠想象成: 我要辦一座學校(全局),會有多個年級(函數/塊級做用域),而後呢每一個年級裏面又有多個班級(子函數/塊級做用域),每一個班級又會有跟細的組織結構
可是呢 我這裏只是想好了怎麼安排制度(某個班級考試時,若是班級本身沒有試卷,那須要的試卷應該向對應的年級拿,年級沒有,再去找學校要),但至於運行起來後,年級有多少試卷,是否還有做業,就要看年級私底下的安排了(這個這裏先不去理解 看看就好)