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)可以再劃分為三種類型:
ES6
之後才出現的唷!var globalVariable = "哇系全域變數";
function global() {
console.log(globalVariable);
}
global(); // 輸出 "哇系全域變數 "
globalVariable
是在全域中定義的,因此可以視它為全域作用域的物件,所以它能夠在所有程式碼中訪問,包含global
函式內。
補充:為什麼會說可以將globalVariable
視為全域物件呢?如果使用window.globalVariable
也會印出"哇系全域變數"
的值唷~
function a() {
var b = "哇系函式裡面的值";
console.log(b);
}
a(); // 輸出: " 哇系函式裡面的值 "
console.log(b); // 錯誤: b is not defined
當b
變數被宣告在a 函式
裡面,因此b
將會是屬於函式作用域(Function scope),所以b
只能夠在所屬的函式中被訪問,無法再外部訪問。
在ES6之前的JavaScript主要是依賴於全域作用域和函數作用域,還記得DAY1中提到var
的作用域是屬於「函式作用域嗎」?
如果在非函式(if 、 for...loop)中使用 var 來定義變數,var 的值會變為全域物件
複習一下程式碼
if(true){
var a = "我在if裡面"
}
console.log(a) // 印出 "我在if裡面"
從上方程式碼可以看出定義在if
裡面的a
,可以在外層成功訪問。
為了解決這個問題,於是在ES6新增了let
和const
,ˊ這兩者的作用域都屬於「區塊作用域」,「區塊作用域」的範圍以{}
來切分。
if(true){
let a = "我是區塊作用域,外層拿不到我"
}
console.log(a) // 錯誤:Uncaught ReferenceError: a is not defined
let a = "007"
function b(){
console.log(a)
}
b() // 印出 "007"
在b
函式內訪問變數a
,如果再當前的範圍中找不到相關的值時,就會一層一層往外找,直到找到為止,當內層找不到a
,則往外找到頂層的a
也就會印出"007"
,如果往外層也找不到,JavaScript就會提示錯誤訊息表示找不到該變數唷!
參考文章:
MDN
重新認識 JavaScript: Day 10 函式 Functions 的基本概念