iT邦幫忙

2023 iThome 鐵人賽

DAY 3
1
Modern Web

那些你可能要知道的前端知識系列 第 3

【day3】(JavaScript) 作用域 Scope

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20230906/20148303SxVnlVksh8.png

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. Scopes can also be layered in a hierarchy, so that child scopes have access to parent scopes, but not vice versa.

MDN文件中可以了解到Scope的定義

  • 外層不能夠存取到內層的變數,但是內層可以存取外層的變數
  • 只要變數離開有效存取的範圍,即會無效

作用域(Scope)可以再劃分為三種類型:

  • 全域作用域 Global scope
  • 函式作用域 Function scope
  • 區塊作用域 Block scope => ES6之後才出現的唷!

全域作用域 Global scope

var globalVariable = "哇系全域變數";

function global() {
    console.log(globalVariable);
}

global();  // 輸出 "哇系全域變數 "

globalVariable是在全域中定義的,因此可以視它為全域作用域的物件,所以它能夠在所有程式碼中訪問,包含global函式內。

補充:為什麼會說可以將globalVariable視為全域物件呢?如果使用window.globalVariable也會印出"哇系全域變數"的值唷~

函式作用域 Function scope

function a() {
    var b = "哇系函式裡面的值";
    console.log(b);
}

a();  // 輸出: " 哇系函式裡面的值 "
console.log(b);  // 錯誤: b is not defined

b變數被宣告在a 函式裡面,因此b將會是屬於函式作用域(Function scope),所以b只能夠在所屬的函式中被訪問,無法再外部訪問。

區塊作用域 Block scope (ES6)

在ES6之前的JavaScript主要是依賴於全域作用域和函數作用域,還記得DAY1中提到var的作用域是屬於「函式作用域嗎」?
如果在非函式(if 、 for...loop)中使用 var 來定義變數,var 的值會變為全域物件
複習一下程式碼

if(true){
    var a = "我在if裡面"
}

console.log(a) // 印出 "我在if裡面"

從上方程式碼可以看出定義在if裡面的a,可以在外層成功訪問。

為了解決這個問題,於是在ES6新增了letconst,ˊ這兩者的作用域都屬於「區塊作用域」,「區塊作用域」的範圍以{}來切分。

if(true){
    let a = "我是區塊作用域,外層拿不到我"
}

console.log(a) // 錯誤:Uncaught ReferenceError: a is not defined

作用域鏈 (Scope Chain)

let a = "007"

function b(){
    console.log(a)
}

b() // 印出 "007"

b函式內訪問變數a,如果再當前的範圍中找不到相關的值時,就會一層一層往外找,直到找到為止,當內層找不到a,則往外找到頂層的a也就會印出"007",如果往外層也找不到,JavaScript就會提示錯誤訊息表示找不到該變數唷!

參考文章:
MDN
重新認識 JavaScript: Day 10 函式 Functions 的基本概念


上一篇
【day2】(JavaScript) ==、=== 的區別
下一篇
【day4】(Javascript) 提升Hoisting
系列文
那些你可能要知道的前端知識30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言