做用域是指程序源代碼中定義變量的區域bash
做用域規定了如何查找變量,也就是肯定當前執行代碼對變量的訪問權限函數
一言蔽之,「做用域就是一套規則,用於肯定在何處以及如何查找變量(標識符) 的規則」 因而:spa
var a = 'programmer'
function foo() {
var b = 'iceman'
console.log(a); // programmer
console.log(b); // iceman
console.log(c); // c is not defined
}
foo()
複製代碼
如上代碼,在函數 foo 內,輸出了三個變量,那麼這三個變量都是從哪來的呢。code
而所謂的做用域,在此時就體現出來了,我要在 foo 獲取某個 變量(標識符),我要怎麼獲取指定的變量,怎麼獲取cdn
咱們須要知道的是,做用域分爲 函數做用域和全局做用域 (後面還會有塊級做用局、模塊做用域);blog
上面的代碼中能夠這樣解讀:ip
a: 輸出變量 a => 查找變量 a => 未在 foo 函數做用域中找到 => 去上一級做用域中尋找 => 找到 a => 輸出 a => 'programmer'作用域
b: 輸出變量 b => 查找變量 b => 在 foo 函數做用域中找到 b => 輸出 b => 'iceman'string
c: 輸出變量 c => 查找變量 c => 未在 foo 函數做用域中找到 => 去上一級做用域中尋找 => 未找到 c => 搜變全局也未找到變量 c => 拋出錯誤 => c is not definedit
綜上所述,這就是 名爲 做用域 的查找 規則 咱們在查找 a 的時候就已經發現,如今 foo 函數做用域中查找,沒有找到,又去上一層做用域中查找,直至找到全局做用域,就好像是順着一條鏈條從下往上查找,這條鏈條,咱們就稱之爲做用域鏈
暫且知道 做用域 && 做用域鏈,至於它到底是什麼,以及怎麼產生的,咱們後續討論
在 ES6 以前, JavaScript 中只存在函數做用域和全局做用域;
全局做用域: 程序代碼最大的做用域,只有一個,這個做用域就能夠想象成一個海洋,或者 root 函數做用域: 又稱局部做用域,局部做用域 顧名思義,小範圍的,在程序代碼中可存在多個
所謂的做用域嵌套 就體現出來了,全局做用域嵌套局部做用局,而局部做用域裏面還能夠繼續嵌套局部做用域,就像一個洋蔥卷
詞法做用域:函數的做用域在定義 聲明的時候就決定了 動態做用域:函數的做用域是在函數調用的時候才決定的
var value = 1
function foo() {
console.log(value);
}
function bar() {
var value = 2
foo()
}
bar() // 輸出 1
複製代碼
如上:foo 做用域內沒有定義 value 在它所定義的上級做用域裏定義了一個 value,在 bar 環境內調用 foo,因爲 JavaScript 採用的是詞法做用域,也就是在定義時就肯定了 做用域,因此 foo 會獲取到 它的所定義位置的上一層做用域中的 value 而不是 bar 中的 value
而動態做用域就會與詞法做用域相反,採用動態做用域的語言不多,若是是動態做用域,函數的做用域是由調用的時候肯定的,就會輸出 bar 內的 value