看到標題,相信你們有點懵逼,什麼是靜態做用域?什麼又是動態做用域?先拋開這些不談,咱們先來看一個題目,這個題目來自於《你不知道的 JavaScript》(上)。git
function foo(){
console.log(a);
}
function bar(){
var a = 3;
foo();
}
var a = 2;
bar();
複製代碼
執行以上代碼,輸出是什麼?咱們發現輸出是2?這是啥狀況,爲何不是 3,而是 2?究竟是什麼緣由形成的?由於 JavaScript 是採用詞法做用域的,那麼 a 在 foo 函數內找不到,那麼按照詞法做用域, a 會去函數定義時的環境中找,也就是 2。github
靜態做用域(即詞法做用域)中的函數遇到既不是形參也不是函數內部定義的局部變量的變量時,會去函數定義時的環境中查詢。函數
動態做用域中的函數遇到既不是形參也不是函數內部定義的局部變量的變量時,到函數調用時的環境中查。ui
既不是形參也不是函數內部定義的局部變量的變量即自由變量。形參或函數內部定義的局部變量即約束變量。spa
經過上面的描述,咱們再看一題。code
var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f();
}
checkscope();
複製代碼
var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f;
}
checkscope()();
複製代碼
猜猜兩段代碼各返回什麼?兩段代碼都返回 local scope
。由於 scope
在 f
函數內找不到,因此會在函數定義時的做用域查找,因此是 local scope
。ip