iT邦幫忙

2021 iThome 鐵人賽

DAY 11
0

Hoisting

能在宣告變數、函式、物件與其他型別前先進行使用,但是初始化並不會被提升。
因為 JavaScript 分成編譯跟執行兩個階段,在編譯階段會把宣告的東西存在記憶體中,而等到執行階段就可以拿出來用了。
EX:

//函式
SayHi("Ivy"); //Hi, Ivy.

function SayHI(name) {
  console.log("Hi, " + name + "." );
  
  //變數
  console.log(a); //undefined
  var a = 1234;
}

剛剛上面的變數a,因為只有宣告會被提升,因此結果出來並不是 ReferenceError: a is not defined,而賦值的部分沒有,所以才會出現 undefined,因為所有變數一開始都會被預設為 undefined。

Hoisting 並不是文件規範的詞彙

因為 JavaScript engine 執行時,事實上沒有東西真正被 「Hoist」,所以我們只能說「想像」會比較好理解。
所以剛剛上面的變數a的範例可以想像成:

var a;
console.log(a);
a=1234;

所以會出現undified就不覺得奇怪了。

**小提醒: 如果有變數與函式是同名的宣告,則在優先權上函式的提升會高於變數:
請看下面範例。
EX:

console.log(a); // ƒ a(){return 'Good morning!';}
var a = "Ivy";

function a(){
return 'Good morning!';
}

let 與 const 沒有 hoisting?

事實上, let 與 const 是有 hoisting的,但是當你嘗試先宣告再使用時,會出現TDZ error。
他們不會初始化為 undefined,而且在賦值之前試圖取值會發生錯誤(temporal dead zone)。

These variable declarations only become initialized when they are evaluated during runtime. The >time between these variables being declared and being evaluated is referred to as the temporal >dead zone. If you try to access these variables within this dead zone, you will get the >reference error above.

這強迫你不要在宣告前使用他們。

而TDZ error 是為了 const, 因為const 不能被重新賦值(記得所有變數在預設狀態會被設為undifined)
而let是與const一起推出的,let 也是用這樣的模式。

想進一步瞭解可以去看這篇文章,我覺得寫得蠻詳細的
Ashe Li [day21] YDKJS (Scope) : Hoisting ? let 會 Hoist 嗎 ?

參考資料:
How Hoisting Works With ‘let’ and ‘const’ in Javascript
MDN 提升(Hoisting)
Huli 我知道你懂 hoisting,可是你了解到多深?
Shubo 的程式教學筆記


上一篇
Expression 與 Statement
下一篇
JavaScript | By value V.S. By reference(傳值 V.S. 傳參考)
系列文
開始入坑網頁吧!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言