JavaScript 核心觀念(3)-的語法作用域(Lexical scope)
嗨大家好嗎?
我是Kris,今天要來跟大家講一個我覺得很重要的東西
算是解題時很常用到的基本觀念哦~
相信大家應該多少都有聽過全域變數、區域變數吧
今天要來講的語法作用域就跟這個有關係
讓我們開始吧!
JS是採用語法作用域,那什麼是語法作用域呢?
就是我們定義的變數能夠發揮功能的區域!
接下來可以跟著動手做做看
建立一個function 叫做callName
在函式內定義變數Ming並且給予'小明'的值
再用console.log列印出Ming的值。
在主程式呼叫callName(); //這樣callName這個function才會運行
會得到結果:上方圖1右方網頁上反白的資料(會印出小明)
接著假設我們把 console.log那一行移至呼叫callName(); 的下一行
如同下圖2
會得到結果:圖2右方網頁上寫著錯誤訊息-Ming is not defined(Ming未定義)
這是因為JS有語法作用域的關係
因此var Ming = '小明' 能夠發揮功能的區域只在callName這個function內(大括號{}裡面)
在外層是讀不到的,這就是因為作用域的關係~
語法作用域也跟JS怎麼運行有很大的關係
講到語法作用域呢會牽扯到靜態作用域&動態作用域
靜態作用域也就是語法作用域(JS使用的)
指的是在語法解析什就確定能夠發揮功能的區域(就像上面例子寫callName函式時就確定了)
而動態作用域指的是在函式被調用的時候才會決定作用域
重點筆記👇
靜態作用域
變數的作用域在語法解析時,就已經確定作用域,並且不會改變。
動態作用域
變數的作用域在函式調用時才決定。
JS的作用域是一層一層向內的
最外層有一個全域的作用域,內層是由function所包住(全域作用域所定義的變數=全域變數)
如下圖,callMe和fn2就是兩個獨立的作用域
如果內層作用域有需要一些變數,但是此作用域內沒有這個變數的時候
就會向外查找,找到的話就會拿來使用
找不到時就會出現 變數is not defined的錯誤訊息
接下來用程式碼來解釋一下靜態作用域&動態作用域
先將剛剛的code註解,再來打新的code
首先定義變數value = 1
再建立兩個function分別是fn1()和fn2()
fn1()裡使用console.log列印出value的值
fn2()裡定義變數value = 2; 並且呼叫fn1();
在全域作用域呼叫fn2();
程式碼如下圖,可以跟著做哦
這段code運行的順序是
1.定義變數value = 1;
2.執行fn2(); *小提示:如果程式碼內都沒有呼叫fn2()的話,fn2裡的內容是不會被執行的哦*
3.在fn2的時候重新宣告變數value = 2;
4.執行fn1();
5.console.log() 列印出value的值
此時value的值會列印出1
因為JS是語法作用域(靜態作用域)的關係,在撰寫時作用域就已經決定了,且不會改變
因此最上面的value = 1; 是全域變數,作用域包含了兩個fn,如下圖
评论
发表评论