iT邦幫忙

2024 iThome 鐵人賽

DAY 10
2

JavaScript 中的作用域有幾種類型,主要包括:

  • 全域作用域(Global Scope)
  • 函式作用域(Function Scope)
  • 區塊作用域(Block Scope)

scope 作用域

MDN的說明:

The scope is the current context of execution in which values and expressions are "visible" or can be referenced. If a variable or expression is not in the current scope, it will not be available for use.

作用域就像是一個範圍概念,其中值或表達式是可見的或可被引用,如不在這個範圍內,將無法使用值或表達式。

全域作用域(Global Scope)

JavaScript執行時,會創建一個全域的執行環境,在這裡宣告的變數叫做全域變數。全域變數在程式中任何地方都能使用到。

在Node.js中,全域物件是global
在瀏覽器中,全域物件是window

範例:

let global = "我是全域";

function sayHello() {
    console.log(global); //在函式中印出變數global 
}

sayHello();  // "我是全域"
console.log(global);  // "我是全域"

因為global此變數在全域宣告,在任何地方都能被存取。即便有函式作用域,因「作用域鍊」的關係,會往外層找到此變數而印出。

函式作用域(Function Scope)

變數只在函式內部存取。當函式被呼叫時,會產生函式的執行環境,當函式結束時,函式的執行環境也結束了,因此裡面宣告的變數就無法再被存取。

範例:

function sayHello() {
    let innerVar = "我是函式內的變數";
    console.log(innerVar);  //?
}

sayHello(); 
console.log(innerVar);  //?

執行結果:
function scope
呼叫sayHello函式,裡面有順利印出innerVar變數的內容"我是函式內的變數"

但在全域呼叫innerVar變數時,瀏覽器會報錯Uncaught ReferenceError: innerVar is not defined
證明此變數只作用在函式內,函式結束裡面變數也就無法存取。

區塊作用域(Block Scope)

適用letconst關鍵字宣告的變數,只能作用在區塊{}內部,任何包含大括號 {} 的語法,例如if...elseforwhiletry...catch等,都會形成區塊作用域。

if (true) {
    let innerVar = "我是區塊變數";
    console.log(innerVar);  // "我是區塊變數"
}

console.log(innerVar);  // 報錯

執行結果:
block scope
innerVar變數在if區塊裡面有順利印出innerVar變數的內容。
而在區塊外面要存取時,瀏覽器一樣會報錯Uncaught ReferenceError: innerVar is not defined

如果是var關鍵字宣告的變數,在區塊外仍能存取!var只會被限制在function,其他都關不住它XD
不過現在很少使用var了,都使用let和const~

把剛剛題目改成var宣告:

if (true) {
    var innerVar = "我是區塊變數";
    console.log(innerVar);  // "我是區塊變數"
}

console.log(innerVar);  // 報錯

var變數宣告

scope chain 作用域鍊

JavaScript會嘗試在當前的作用域尋找該變數,如找不到就往外層找,直到找到該變數或是到全域,全域仍找不到則會拋出ReferenceError錯誤。

let global = "我是全域變數";

function outerFunction() {
    let innerVar = "我是函式內變數";
    
    function innerFunction() {
        console.log(global);  // 在全域找到變數
        console.log(innerVar);  // 在outerFunction內找到變數
    }
    
    innerFunction();
}

outerFunction(); 

//"我是全域變數"
//"我是函式內變數"

以上分享~謝謝!

參考資料

MDN - scope
JS 原力覺醒 Day04 - Function Scope / Block Scope
JS 原力覺醒 Day05 - Scope Chain
Javascript 的作用域 (Scope) 與作用域鏈 (Scope Chain) 是什麼?


上一篇
[Day 09] try...catch 例外處理
下一篇
[Day 11] 運算式與運算子(上) - 介紹
系列文
JavaScript學習筆記13
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言