iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 17
0
Modern Web

跟著 YDKJS 作者 Kyle Simpson 打造全新 JavaScript Mindset系列 第 17

[day16] YDKJS (Scope) : Lexical Scope Review(投影片當動畫),Error 種類

  • 分享至 

  • xImage
  •  

大家記得要點投影片 Link!

https://www.slideshare.net/AsheLi1/day16-ydkjs-scope-lexical-scope-review-178412966


  1. JavaScript 不是 interpreter language (直譯式語言)。
  2. JavaScript 是 two pass processing。
  • compile time 決定 Scope
  • Executing time 執行 statement (assignment, expression)
  1. 每一個不同顏色的小球或木桶,其實就不同 變數物件(Variable Object, VO)

如果是 function 內部,稱作 執行中物件(Activation Object, AO)
> - 彼此獨立(所以看到不同的function 我們才會給不同顏色)。
> - 如果內層沒有變數宣告,可以向外層詢問,一直重複到達到全域 Scope 為止。
> - 書中稱作 建築的隱喻(Building on Metaphors):
最下面是我們開始的 Scope,
往上找到頂層(全域 作用域)就結束。
>

Error:

沒有找到 variable

  • 如果 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."

    • 如果在 Strict模式 的前提下,不會建立,這樣的 Error throw 結果稱作ReferenceError ,和 RHS 一樣。

有找到 variable

  • 如果 variable 有找到,但你嘗試做些不可能的操作,這時候的 Error throw 結果稱作 TypeError

    比如 將一個非函式的值作為函式執行
    比如 引用 null 或者 undefined 值的屬性

總結 Error :

  • ReferenceError 是關於 作用域 解析失敗
  • TypeError 暗示著 作用域 解析成功了,但是試圖對這個結果進行了一個非法/不可能的動作。

在電腦前,試著「說出來」

很傳統的方法,不過可以確實反應有沒有理解。

一樣的 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

  • Memory 那行如果有指向,可以視為 build-in global scope
  • 色塊可以視為 Execution Context
    • 紅色 :global

希望沒有錯誤,可以幫忙揪錯 ~

參考資料:

ECMA-262 Javascript核心

這篇講很細,如果理解 YDKJS 用對話的方式,回來補 Spec 可以更深入理解。
如果習慣讀英文,可以參考這邊

想看影片比較直觀:huli 的 lidemy,試看章節:從 ECMAScript 看作用域

我沒有買這堂課,不過這段剛好可以試看,可以當補充資料。


上一篇
[day15] YDKJS (Scope) : 執行環境(Execution Context)的角色扮演遊戲(Executing time篇 )
下一篇
[day17] YDKJS (Scope) : 不要耍白目 JavaScript! (Dynamic Global Variable, Strict Mode)
系列文
跟著 YDKJS 作者 Kyle Simpson 打造全新 JavaScript Mindset31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言