iT邦幫忙

2021 iThome 鐵人賽

DAY 3
2
自我挑戰組

JavaScript 核心觀念系列 第 3

【Day03】語法作用域(Lexical scope)

  • 分享至 

  • xImage
  •  

今天要來介紹 JavaScript 的作用域,

JavaScript 是採用語法作用域(靜態作用域)

首先我們先來看一個函式執行:

function callName() {
    var ming = '小明';
    console.log(ming);
}

callName();

此時顯示的結果為 小明

但如果將 console.log() 放到函式外面時,

function callName() {
    var ming = '小明';
}

callName();

console.log(ming);

會顯示 ReferenceError: ming is not defined

表示 ming 沒有被定義,

為什麼會這樣呢?

這就跟 JavaScript 的作用域有關係了

靜態作用域和動態作用域

之前有說過 JavaScript 是直譯式語言,是利用直譯器來生成代碼後運行,

而作用域在代碼解析時,就已經確定作用域了,這就是語法作用域

也就是當我們在撰寫程式碼的時候,作用域就已經決定好了,

動態作用域是在調用函式的時候,才決定作用域。

以圖形表示作用域決定位置:

將上圖簡單整理的話變成:

  1. 語法作用域(靜態作用域)

    在語法解析時,就已經確定作用域,也就是當我們在程式碼寫好的時候,作用域就已經決定好了。

  2. 動態作用域

    在調用函式的時候,才決定作用域。

JavaScript 作用域

JavaScript 的作用域是一層一層包著的,每一個函式都是一個作用域,而最外層是全域

fn1 需要使用變數,但作用域內沒有該變數時,會向外查找

當外層該變數時會直接使用,

當外層沒有該變數時,會顯示 ReferenceError: xxx is not defined

接下來我們看一個範例:

var value = 1;

function fn1() {
    console.log(value);
}

function fn2() {
    var value = 2;
    fn1();
}

fn2();

該範例顯示結果為 1

圖解:

此時 fn1 內沒有 value 這個變數,所以會向外查找,

而 JavaScript 的作用域為語法作用域

因此 fn1 的外層為全域,而不是 fn2,所以 value 會指向全域中的值 1

但如果是動態作用域的話,那結果會顯示 2

PS:這只是舉例動態作用域會顯示的結果而已,JavaScript 中這程式碼不管執行幾次都只會顯示 1

因為 fn1fn2 調用時,fn1 外層的作用域會變成 fn2 的作用域,因此 value 會指向 fn2 中的值 2

以上就是關於作用域的部分了,明天說明執行環境與執行堆疊的部分。


上一篇
【Day02】錯誤範例的 RHS 和 LHS
下一篇
【Day04】執行環境與執行堆疊
系列文
JavaScript 核心觀念30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
qpalzm
iT邦研究生 5 級 ‧ 2021-09-08 15:46:12

fucntion !== function XD

weiwei iT邦新手 5 級 ‧ 2021-09-08 18:20:10 檢舉

打太快沒注意到
已經修改好了
感謝提醒

我要留言

立即登入留言