https://www.slideshare.net/AsheLi1/day16-ydkjs-scope-lexical-scope-review-178412966
變數物件(Variable Object, VO)
如果是 function 內部,稱作
執行中物件(Activation Object, AO)
,
> - 彼此獨立(所以看到不同的function 我們才會給不同顏色)。
> - 如果內層沒有變數宣告,可以向外層詢問,一直重複到達到全域 Scope 為止。
> - 書中稱作 建築的隱喻(Building on Metaphors):
最下面是我們開始的 Scope,
往上找到頂層(全域 作用域)就結束。
>
如果 RHS (常用 source position ) 沒有找到 variable,特別強調找到 global Scope 都失敗,這樣的 Error throw 結果稱作ReferenceError
.
如果 LHS (常用 target position ) 沒有找到 variable,特別強調找到 global Scope都失敗,不是 Strict模式 的前提下,JavaScript 會自作聰明建立在 global Scope(因為找到最後跑去global) ,建立找不到的 variable。
JavsScript : "No, there wasn't one before, but I was helpful and created one for you."
ReferenceError
,和 RHS 一樣。TypeError
比如 將一個非函式的值作為函式執行
比如 引用 null 或者 undefined 值的屬性
總結 Error :
很傳統的方法,不過可以確實反應有沒有理解。
一樣的 Code :
var teacher = "Kyle";
function otherClass(){
var teacher = "Suzy";
console.log("Welcome!");
}
function ask(){
var question = "Why?";
console.log(question);
}
otherClass();
ask();
第一階段 compilation
角色: compiler, scope manager
訊息:「Scope manager 已經創造一個 紅色桶子(global scope)。」
compiler:「嘿!
紅色桶子 的 manager
, 你有聽說過有一個東西(formal declaration for variable)叫做teacher
嗎?」
* formal declaration for variable ,其實就是 Identifier紅色桶子 的 manager : 『我沒有聽過耶。我這邊有一個紅色桶子!把那個紅色小球丟進來吧!』
compiler:「嘿!
紅色桶子 的 manager
, 你有聽說過有一個東西(Identifier)叫做otherClass
嗎?」
紅色桶子 的 manager : 『我沒有聽過耶。』
紅色桶子 的 manager : 『我這邊有一個紅色桶子!把那個紅色小球(Identifier)丟進來吧!』
訊息:「Scope manager 已經創造一個 藍色桶子(function scope)。」
compiler:「嘿!
藍色桶子 的 manager
, 你有聽說過有一個東西(Identifier)叫做teacher
嗎?」
藍色桶子 的 manager : 『我沒有聽過耶。』
藍色桶子 的 manager : 『我這邊有一個藍色桶子!把那個藍色小球(Identifier)丟進來吧!』
compiler:「嘿!
紅色桶子 的 manager
, 你有聽說過有一個東西(Identifier)叫做ask
嗎?」
紅色桶子 的 manager : 『我沒有聽過耶。』
紅色桶子 的 manager : 『我這邊有一個紅色桶子!把那個紅色小球(Identifier)丟進來吧!』
訊息:「Scope manager 已經創造一個 綠色桶子(function scope)。」
compiler:「嘿!
綠色桶子 的 manager
, 你有聽說過有一個東西(Identifier)叫做question
嗎?」
綠色桶子 的 manager : 『我沒有聽過耶。』
綠色桶子 的 manager : 『我這邊有一個綠色桶子!把那個綠色小球(Identifier)丟進來吧!』
第二階段 pass execution
角色: JavaScript engin, scope manager
道具: 第一階段的規劃書
line 1
。
JavaScript engin:「嘿!紅色木桶的 Scope manager, 我有一個 變數 是一個 target reference ,叫做
teacher
, 你有聽說過有一個叫做 teacher 的小球嗎?」
紅色木桶的 Scope manager : 『Yes , 我知道它,拿去吧!』
訊息 : 「 回傳 JavaScript engin 把值寫入 identifier。 」
line 3
。
// Skip line 3 ~ 12
line 13
。
JavaScript engin:「嘿!紅色木桶的 Scope manager, 我有一個 identifier 是一個 source reference ,叫做
otherClass
, 你有聽說過有一個叫做 otherClass 的小球嗎?」
紅色木桶的 Scope manager : 『Yes , 我知道它,拿去吧!』
訊息 : 「 回傳 JavaScript engin 一個 function , 而且是 藍色木桶裝的。 」
line 4
JavaScript engin:「嘿! 藍色木桶的 Scope manager, 我有一個 變數 是一個 target reference ,叫做
teacher
, 你有聽說過有一個叫做 teacher 的小球嗎?」
藍色木桶的 Scope manager : 『Yes , 我知道它,拿去吧!』
訊息 : 「 回傳 JavaScript engin 把值寫入 identifier。 」
line 5
JavaScript engin:「嘿!藍色木桶的 Scope manager, 我有一個 identifier 是一個 source reference ,叫做
console
, 你有聽說過有一個叫做 console 的小球嗎?」
藍色木桶的 Scope manager : 『No , 我沒看過它。』
藍色木桶的 Scope manager : 『我幫你問看看 紅色木桶的 Scope manager 。』
紅色木桶的 Scope manager : 『Yes , 我知道它,拿去吧!』
訊息 : 「 回傳 JavaScript engin 一個 object , 而且是 紅色木桶裝的。 」
line 14
JavaScript engin:「嘿!紅色木桶的 Scope manager, 我有一個 identifier 是一個 source reference ,叫做
ask
, 你有聽說過有一個叫做 ask 的小球嗎?」
紅色木桶的 Scope manager : 『Yes , 我知道它,拿去吧!』
訊息 : 「 回傳 JavaScript engin 一個 function , 而且是 綠色木桶裝的。 」
function 的 line 9
JavaScript engin:「嘿! 綠色木桶的 Scope manager, 我有一個 變數 是一個 target reference ,叫做
question
, 你有聽說過有一個叫做 question 的小球嗎?」
綠色木桶的 Scope manager : 『Yes , 我知道它,拿去吧!』
訊息 : 「 回傳 JavaScript engin 把值寫入 identifier。 」
JavaScript engin:「嘿!綠色木桶的 Scope manager, 我有一個 identifier 是一個 source reference ,叫做
console
, 你有聽說過有一個叫做 console 的小球嗎?」
綠色木桶的 Scope manager : 『No , 我沒看過它。』
綠色木桶的 Scope manager : 『我幫你問看看 紅色木桶的 Scope manager 。』
紅色木桶的 Scope manager : 『Yes , 我知道它,拿去吧!』
訊息 : 「 回傳 JavaScript engin 一個 object , 而且是 紅色木桶裝的。 」
function 的 line 10
JavaScript engin:「嘿!綠色木桶的 Scope manager, 我有一個 identifier 是一個 source reference ,叫做
question
, 你有聽說過有一個叫做 question 的小球嗎?」
綠色木桶的 Scope manager : 『Yes , 我知道它,拿去吧!』
訊息 : 「 回傳 JavaScript engin 一個 值 , 而且是 綠色木桶裝的。 」
不會內嵌 slideshare QQ
https://www.slideshare.net/AsheLi1/day16-ydkjs-scope-lexical-scope-review-178412966
希望沒有錯誤,可以幫忙揪錯 ~
參考資料:
這篇講很細,如果理解 YDKJS 用對話的方式,回來補 Spec 可以更深入理解。
如果習慣讀英文,可以參考這邊
想看影片比較直觀:huli 的 lidemy,試看章節:從 ECMAScript 看作用域
我沒有買這堂課,不過這段剛好可以試看,可以當補充資料。