# ⬆️向上提升🆙🆙🆙 ## 何謂 hoisting(向上提升)?以 let、const、var、function 為例 ```javascript= Fn("哈哈"); function Fn(str){ console.log("這下你GG了吧!"+str); } // 印出"這下你GG了吧!哈哈" 為什麼執行後有印出來, // 執行的時候不是還沒宣告嗎? console.log(num) var num = 45; // 結果應該是 num is not defined吧。 // 結果居然是 undefined !! ```  >Javascript 執行的運作原理可以大致分成創造跟執行階段, >JS 會分開做在程式開始時候,會先將函式與變數宣告到記憶體中, >之後才會依序執行流程,但是只有宣告並不會進行賦值, >所以可以看到上面案例 num 變數是 undefined 不是 not defined 也不是45。 ```javascript= // 那我們來看另外的案例 function show(num){ var num; console.log(num); num = 0; } show(5) // 照剛剛 hoisting 的概念 應該會印出 undefined 吧。 // 結果卻印出了 5 ```  >在提升的過程中,傳入的參數也是會進行值得賦予, >可以看成是 ```javascript= function show(num){ var num = 5; var num; console.log(num); num = 0; } // 因為 hoisting 的緣故 // 中間執行的狀況變成 var num; // 參數 hoisting var num; num = 5; console.log(num) //最後還有一種情形 console.log(Fn) var Fn; function Fn(){} // 結果印出了 ƒ Fn(){} // function 也會 hoisting 優先權還比變數還高 😵💫 ``` >function 的 hoisting 的權限高於變數,以便於如果沒宣告就不能使用, >那將導致使用者必須將所有函式都寫在開頭,且函式也無法互相呼叫。 ```javascript= // 以下為函式互相呼叫的案例 function loop(n){ if(n<5){ calcFn(++n) } } function calcFn(n){ console.log(n,n%2 ? "奇數": "偶數") loop(n) } loop(1) // 2 '偶數' 3 '奇數' 4 '偶數' 5 '奇數' // 可以正確顯示出升冪並顯示奇數偶數 ``` >所以 function 具備 hoisting 看起來必要性是必然的。 ```javascript= console.log(num) let num // 有兩種顯示錯誤 ReferenceError: num is not defined // Cannot access 'num' before initialization // 如果在 node 高版本環境則會顯示這個 ``` >let const看似不會,其實也會hoisting ```javascript= // 這個案例就可以看出 let 也是有 hoisting 的機制 var num = 5; function show(){ console.log(num) let num } show() // 結果沒意外應該是印出 5 // 結果卻印出了 ReferenceError: num is not defined ``` >可見得 let 也將 num 提升了,只是作用行為跟 var 不同, >var 做的提升宣告的變數會被進行初始化為 undefined ,而 let const 則是 >不會進行初始化 undefined ,所以在賦予值之前呼叫則會報錯, Javascript 在 >提升後與賦予前的期間存在一個 TemporalDeadZone 的區域簡稱 TDZ  ```javascript= // 案例 function calc(){ var num1 = 5; //num3 的TDZ開始 var num2 = 10; console.log(num3); // 報錯 if(num2>num1){ console.log(num2) } let num3 = 15; // num3 TDZ結束 } calc() ``` ## 寫在結尾 hoisting 確實的解決了 JS 上面 function 互相呼叫的問題, 而在名稱衝突發生時優先順序高到低為: 1. 函式宣告 function declaration 1. 函式參數 function arguments 1. 變數宣告 variable ### 參考資料 [提升(Hoisting)- MDN](https://developer.mozilla.org/zh-TW/docs/Glossary/Hoisting) [D6 - 你不知道 Combo : 主菜 Scope 字彙環境](https://ithelp.ithome.com.tw/articles/10269077) [[第十七週] JavaScript 進階:從 EC 來理解 Hoisting](https://yakimhsu.com/project/project_w17_advancedJS_02_Hoisting.html) [我知道你懂 hoisting,可是你了解到多深?](https://github.com/aszx87410/blog/issues/34) ###### tags: `Javascript` `JS 直播班 - 2021 秋季班` `六角學院`
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up