執行環境與作用域
執行環境與作用域
JavaScript 是屬於直譯式語言,它會直接透過直譯器來產生代碼,並且運行代碼。
執行的錯誤情境
- RHS (Right Hand Side) :RHS 取值來自於右側的變數上
- LHS (Left Hand Side) :LHS 取值來自於左側的變數上
1
2把「小明」賦予到左側的變數上,就稱為 LHS
var ming = '小明'1
2右邊的值是使用 RHS 取得變數,並且透過 LHS 賦予到左邊的變數
var min = ming
語法作用域
- 靜態作用域 :語法作用域又稱為 靜態作用域,所以會在與法解析時就已經確定作用域,而且不會再改變。
- 動態作用域 :變數的作用域會在函式調用時才決定。
範圍鍊 Scope Chain
JavaScript 是採用 語法作用域 ,所以當函式建立時,作用域就已經被限制在函式範圍內,當在函式內宣告變數時,外層是無法讀取的。
1 | function fn() { |
也就是說,每個函式的作用域都是獨立的,如果在函式作用域內需要特定變數,但是作用域內並沒有特定變數,此時就會向外查找;
如果向外查找也沒有的話,就會出現 ReferenceError: b is not defined
的錯誤。
而這個向外尋找變數的過程,就叫做 範圍鍊 ,範圍練取決於函式的作用域,與執行環境沒有關係。
1 | var a = 'a' |
容易搞混的靜態作用域 ⚡⚡⚡
函式建立時就已經確定作用域,並且 不會改變
因此以下範例來說,當 fn1 建立時就已經確定了 value 的值為 1,就算在 fn2 重新宣告並呼叫,`value = 2` 的有效作用範圍僅止於 fn2 內,並不會影響 fn1 的內容。
1 | var value = 1 |
執行環境
建立函式後並執行 (呼叫) 函式,會產生執行環境
舉例來說,如果在函式內宣告一個變數,那變數的作用域就會被限制在函式內,但是如果函式沒有被執行,就不產生執行環境,也就不會有任何變數產生。
也就是說,如果函式反覆被執行,就會不斷產生新的執行環境。
全域也有屬於自己的執行環境,建立時機在網頁一開啟,或是後端 Node.js 一開啟時,執行環境就會被建立。
執行堆疊
- 當網頁一開啟時,會先建立全域執行環境
- 呼叫 doSomething 時,就會建立 doSomething 的執行環境,並且堆疊在全域執行環境之上
- 在 doSomething 內呼叫 sayHi 函式,此時 sayHi 的執行環境就會堆疊在 doSomething
執行環境是一層一層堆疊上去,和函式宣告的時機沒有關聯,而是和函式被呼叫的位置有關