iT邦幫忙

2022 iThome 鐵人賽

DAY 22
0
自我挑戰組

I don't know JS yet系列 第 22

[ Day 22 ] I don't know JS yet

  • 分享至 

  • xImage
  •  

今日是 YDKJS - Scope & Closure ch2.md 第二篇心得

Nested Scope

https://ithelp.ithome.com.tw/upload/images/20221031/20151632NhqLdD5gPX.png

綠色的 getCountryName(...) scope 在黃色的 global scope 以內,而紫色的 for...of scope 在綠色的 scope 裡面,這就是 nested scope(黃色->綠色->紫色)。

而當一個 scope 遇到下列這三種不同的 identifier 宣告,會有不同的應對:

  1. function
    如果 identifier 是從 function declaration 而來,像是上圖的 function getCountry(...),則 identifier 會直接與該 function reference 連結起來。
  2. var
    如果 identifier 是由 var 宣告,則該 identifier 初始的值會是 undefined,所以上圖的 var nextCountry = getCountryName(3) 在還未 execution assignment 之前,nextCountry 會是 undefined。
  3. let, const
    在 full declaration-andinitialization 之前,這些 identifier 通通未被初始化,因此也不能被使用(又稱 TDZ)。

我們來看看for...of 的 countries 被 look up 時,engine 與 scope manager 的對話:

Engine: Hey, Scope manager (for getCountryName function), I've a source reference for countries, ever heard of it?
(Function) Scope Manager: No, never heard of it. Try the next outer scope.
Engine: Hey, Scope manager (for the global scope), I've a source reference for coutries, ever heard of it?
(Global) Scope Manager: Yes, it was formally declared, here it is.
...

再來看一個 'non-strict' 模式下的狀況

    function getCountryName() {
        nextCountry = "Japan";
    }
    
    getCountryName();
    // "Japan" --- yuck!

在做 nextCountry looking up 時,engine 與 scope manager 時對話是這樣的:

Engine: Hey Scope manager (function getCountryName), I've a target reference for nextCountry, ever heard of it?
(Function) Scope Manager: No, never heard of it. Try the next outer scope.
Engine: Hey Scope manager (Global scope), I've a target reference for nextCountry, ever heard of it?
(Global) Scope Manager: No, but since we're in non-strice mode, I helped you out and just created a global variable for you, here it is!

如果在嚴謹模式下,Global Scope Manager 會這樣回答:

No, never heard of it. Sorry I've got to throw a ReferenceError.

strict-mode 的 global scope manager 並不會做 accidental global variable 的動作,保證了不會 reference 一個從沒被宣告過的變數。
所以在撰寫程式碼時,最好還是能使用 strice-mode 避免 accidental global variables 產生。


上一篇
[ Day 21 ] I don't know JS yet
下一篇
[ Day 23 ] I don't know JS yet - Shadowing
系列文
I don't know JS yet30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言