JS靜態與動態作用域
JavaScript使用的是靜態作用域,非動態這件事要先提前知道
靜態作用域
懶人包 :
會主動去尋找函數與變量定義時的狀況
例子:
1
2
3
4
5
6
7
8
9
10
11let a = '靜態作用域'
function foo() {
console.log(a);
}
function bar() {
let a = '動態作用域'
foo()
}
bar() // '靜態作用域'分析 :
如果沒有作用域鏈的概念可以參考下面思維
1
2
3
4
5
6
7
81. 前面都很正常的順順執行下來直到bar()
2. 當執行bar時候,會從全局作用域(因為bar執行的地方在全局作用域)裡面尋找bar聲明的地方
3. 進到bar函數作用域裡面(壓棧) // 所在第六行
4. 在bar函數作用域裡面執行foo(),但在該函數作用域裡面沒有聲明foo,因此跑到上一層尋找,就是全局作用域
5. 找到foo聲明的地方,並進入foo作用域裡面
5. 試圖打印出a // 此時所在是第四行
6. 因為foo作用域裡面沒有聲明變量a,因此又跑到全局作用域
7. 找到a(靜態作用域)並打印出來
動態作用域
懶人包:
會到執行時的環境尋找
例子(跟靜態相同):
1
2
3
4
5
6
7
8
9
10
11let a = '靜態作用域'
function foo() {
console.log(a);
}
function bar() {
let a = '動態作用域'
foo()
}
bar() // '動態作用域'分析:
1
2
3
4
5
6
7
8
9
10前面五點都一模一樣直到第六點
1. 前面都很正常的順順執行下來直到bar()
2. 當執行bar時候,會從全局作用域(因為bar執行的地方在全局作用域)裡面尋找bar聲明的地方
3. 進到bar函數作用域裡面(壓棧) // 所在第六行
4. 在bar函數作用域裡面執行foo(),但在該函數作用域裡面沒有聲明foo,因此跑到上一層尋找,就是全局作用域
5. 找到foo聲明的地方,並進入foo作用域裡面
5. 試圖打印出a
6. 這時候找不到a並不會跑到上一層作用域鏈查找,而是回到執行時的環境也就是第八行所在的作用域查找
7. 這時候就會發現a是動態作用域並打印出