前言
JavaScript 採用的是語法作用域,所謂的語法作用域就是你宣告時就已經決定好他的作用域
而語法作用域又分為 動態作用域 和 靜態作用域
什麼是作用域?
語法作用域就是它實際存在的位置,例如 全域環境 及 區域環境
這邊舉例一個區域環境的範例
function sayHi() {
var name = 'Bob';
}
console.log(name); // name is not defined;
當語法宣告位置是在函式內,你將會無法取用。
靜態作用域 & 動態作用域
靜態作用域:
當我們在寫一個函式時,語法解析器就確定了變數的作用域,且不會再改變。動態作用域:
只有在函式呼叫的時候才會決定它的作用域
JavaScript 屬於靜態作用域,所以當程式碼在運行時,就已經決定了作用域,這邊提供範例程式碼
var value = 1; // 全域變數
function fu1 {
console.log(value); // 1
}
function fu2 {
var value = 2; // 區域變數
fu1();
}
fu2();
首先,我們宣告了一個變數 value = 1; 他是一個全域變數。接著宣告兩個函式 fu1及 fu2,最後執行 fn2
執行 fn2 時,我們把變數 value 賦予了另外一個值 2 ,接著執行 fu1 , fu1 因為要印出 value ,因此向外查找 value 這個變數,在全域中找到 value = 1; ,最後 console.log 的結果會是 1
為什麼答案不是 2 呢?因為 fn2 函式的作用域僅在 fn2 內部, fn1 是查找不到 value 等於 2 的。
重要觀念:當前作用域沒有這個變數時 JavaScript 將會一層一層向外查找,也就是所謂的範圍鍊
那動態作用域又是什麼呢?
動態作用域「只有當程式碼運行時才會知道作用域」
var value = 1;
function fu1 {
console.log(value); // 2
}
function fu2 {
var value = 2;
fu1();
}
fu2();
在動態作用域中,因為 fu2 有重新宣告 var value = 2;,執行到 fu1 時,他會向上一層調用的函式 fu2 來查找 value 的值,所以 fu1 實際取得的 value 才會等於 2