iT邦幫忙

2021 iThome 鐵人賽

DAY 2
0
自我挑戰組

JavaScript 奇奇怪怪的核心觀念系列 第 2

(Day2) 範圍鍊與提升

  • 分享至 

  • xImage
  •  

範圍鍊 (Scope Chain)

範圍鍊在 JavaScript 一堆奇奇怪怪的觀念中算是簡單好懂的,簡單來說就是:

『函示內沒有對應的變數、常數或是函示時,他會往外層尋找』

這邊一樣用程式碼來說明。

  function playGame(){
		const gaming = 'PS5'
    console.log(`我要用 ${gaming} 玩遊戲`)
  }
  playGame() //我要用 PS5 玩遊戲

上面這段 gaming 在函示內,因此能正確顯示,這段好像廢話,不過接下來我們試者把 gaming 移到外層全域看看結果如何:

const gaming = 'PS5'
  function playGame(){
    console.log(`我要用 ${gaming} 玩遊戲`)
  }
  playGame() //我要用 PS5 玩遊戲

結果是一樣的,上面 playGame() 函式中因為本身沒有 gaming 常數,因此他會到外層也是全域 (window) ,來獲得 gaming 常數的資料。

接下來便是在函示內外都新增兩個 gaming 來看看結果如何

const gaming = 'PS5'
  function playGame(){
	const gaming = 'Switch'
    console.log(`我要用 ${gaming} 玩遊戲`)
  }
  playGame() //我要用 Switch 玩遊戲

所以結果就是當函示內有相關資料時,變不會往外層尋找,而是直接使用函示內資料。

提升(Hoisting)

(因為 constlet 提升的狀況不一樣,這邊範例先改為使用 varconstlet 會到介紹他們的章節再來提及)

JavaScript 實際編譯並執行程式碼時,會分為兩種階段:

  • 創造階段
  • 執行階段

等創造階段執行完畢,才會進入執行階段,創造階段有幾個重點:

  • 優先建立函示(執行環境) 但不運行,只是建立環境。
  • 再來建立變數,但不會為變數賦值,只是建立一個空值 (undefined) 的變數。
  • 用言語形容這個階段的話就是一個先建立容器,因為這個創造階段的特性,所以這個狀況被稱做 Hoisting (提升)。

而執行階段的重點則是:

  • 執行 呼叫函式 的 XX()
  • 為變數賦予實際的值。

這邊使用上面程式碼,並稍微調一下順序就可驗證上面提到的創造階段。

console.log(gaming) // undefined
var gaming = 'PS5'
playGame() //我要用 PS5 玩遊戲
  function playGame(){
    console.log(`我要用 ${gaming} 玩遊戲`)
  }

console.log(gaming) 這段會因為變數被提升,但尚未賦值因此是 cosnole 會回傳 undefined

playGame() 則是 function playGame() 函示會因為提升效果,而先比被呼叫函示的 playGame() 建立,因此 console 可以正確顯示。

因為提升這個 特性 會讓上面的程式碼,在編譯順序變為:

// 創造階段
//函示優先提升
function playGame(){
  console.log(`我要用 ${gaming} 玩遊戲`)
}
var gaming 

// 執行階段
console.log(gaming) // undefined
gaming = 'PS5'
playGame() //我要用 PS5 玩遊戲

最後要說的是,Hoisting 只是概念,只是幫助我們理解,程式碼在編譯時會這麼做,但他仍只是一種概念, 這點 MDN 文件也有說明到:

提升(Hoisting)是在 ECMAScript® 2015 Language Specification 裡面找不到的專有名詞。它是一種釐清 JaveScript 在執行階段內文如何運行的思路(尤其是在創建和執行階段)。

參考文獻


上一篇
(Day1)執行環境與執行堆疊
下一篇
(Day3) 執行緒與同步&非同步
系列文
JavaScript 奇奇怪怪的核心觀念30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言