做用域是指程序源代碼中定義變量的區域。
做用域規定了如何查找變量,也就是肯定當前執行代碼對變量的訪問權限。
JavaScript 採用詞法做用域(lexical scoping),也就是靜態做用域。
想了解更多關於做用域的問題推薦閱讀《你不知道的JavaScript上卷》第一章(或第一部分),
從編譯原理的角度說明什麼是做用域。歸納的說做用域就是一套設計良好的規則來存儲變量,而且以後能夠方便地找到這些變量。
複製代碼
在你不知道的javascript上卷中是這樣定義的:詞法做用域就是定義在詞法階段的做用域。換句話說,詞法做用域是由你在寫代碼時將變量和塊做用域寫在哪裏來決定的,所以當詞法分析器處理代碼時會保持做用域不變(大部分狀況下是這樣的)。javascript
在JS中詞法做用域的規則:java
例1bash
var a = 2;
function foo() {
var a = 3;
console.log(a); // 3
}
foo();
複製代碼
例2函數
function foo() {
console.log(a); // 2
}
function bar() {
var a = 3;
foo();
}
var a = 2;
bar();
複製代碼
只有函數才能製造做用域結構,那麼只要是代碼,至少有一個做用域,即全局做用域。ui
凡是代碼中有函數,那麼這個函數就構成另外一個做用域。若是函數中還有函數,那麼在這個做用域中就又能夠誕生一個做用域,那麼將這樣的全部做用域列出來,能夠有一個結構:函數內指向函數外的鏈式結構。spa
以上面例2:設計
function foo() {
console.log(a); // 2
}
function bar() {
var a = 3;
foo();
}
var a = 2;
bar();
複製代碼
做用域是由代碼寫在哪裏決定的,而且是逐級包含的。code
咱們用級鏈來表示一下以上代碼塊:cdn
因此不管函數在哪裏被調用,也不管它如何被調用,它的詞法做用域都只由函數被聲明時所處的位置決定。blog
var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f();
}
checkscope();
複製代碼