0%

JS核心(3)-執行環境與作用域-語法作用域

前言

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; 他是一個全域變數。接著宣告兩個函式 fu1fu2,最後執行 fn2

執行 fn2 時,我們把變數 value 賦予了另外一個值 2 ,接著執行 fu1fu1 因為要印出 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