iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 17
0
Modern Web

30天入門JavaScript系列 第 17

【Day 17】範圍 scope

  • 分享至 

  • xImage
  •  


範圍(或作用域、範疇),代表各個識別項(變數跟函式)可以在那些位置被使用。


其實官方文檔用的詞叫字彙環境(Lexical Environment),上面幾個是比較俗稱的叫法,
來看一下官方文檔對字彙環境的說明

https://ithelp.ithome.com.tw/upload/images/20200917/20129836k0SpwDkihA.png





![https://ithelp.ithome.com.tw/upload/images/20200917/20129836pYsqwJVV9M.jpg


我也聽不懂,還是直接看程式吧(

var str = '全域變數的str';
var scope = 'Global';

function funcA() {
  var str = 'funcA內的str';
  var scope = 'A';

  function funcB() {
    var scope = 'B';
    console.log('funcB找到的scope: ' + scope);
    console.log('funcB找到的str: ' + str);
  }
  funcB();
  funcC();
}
function funcC() {
  var scope = 'C';
  console.log('funcC找到的str:' + str);
}

funcA();


JavaScript會依照程式碼的位置來建構字彙環境(下圖用背景顏色區分不同字彙環境)

https://ithelp.ithome.com.tw/upload/images/20200917/20129836ELV1OeRFFy.png

最外部的字彙環境(紅色)的為全域字彙環境,每當有函式被宣告時,就會在內部產生新的字彙環境(藍綠紫色),
像在funcA內建立了funcB,此時funcAfuncB的外部環境,funcA的外部環境為全域字彙環境,
深色的點為該字彙環境內的識別項。

換個角度畫圖,上到下是由內部環境到外部環境
https://ithelp.ithome.com.tw/upload/images/20200917/201298363GCGhuB1Qa.png

當想要存取變數或呼叫函式時,會在目前的字彙環境內尋找是否有該識別項,
目前環境沒有此識別項的話,就往外部環境一層一層找,直到找到識別項。
這種一層一層的關係就叫做範圍鍊(scope chain)
另外這種查找只能由內到外,外部是沒辦法存取內部環境的識別項。



懂甚麼是範圍鍊後,現在來用範圍鍊來解釋上面的程式

程式碼在funcA內呼叫了funcBfuncB需要scopestr兩個的值來印出,
funcB在自己的字彙環境內找到scope變數得到'B'值,但找不到str變數,
依範圍鍊往外部環境的funcA的環境查找,找到funcA內的str變數成功取值。

接著呼叫funcC印出strfuncC一樣在自己的字彙環境找不到str變數,
funcC的外部環境是全域字彙環境,會在全域字彙環境找到str值後印出。

由此例子可以看出範圍鍊只跟程式碼寫的位置有關,
即使funcCfuncB一樣是在funcA內被呼叫的,還是會取得不同的str


執行結果:
https://ithelp.ithome.com.tw/upload/images/20200917/20129836Hs6taiF3tr.png


都畫糞解說圖了字還是好多,累


上一篇
【Day 16】提升Hoisting
下一篇
【Day 18】閉包 closure
系列文
30天入門JavaScript30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言