iT邦幫忙

2024 iThome 鐵人賽

DAY 13
0

提升

指「變數宣告」或是「函式宣告」會被提升到該作用域的頂端,但賦值不會被提升。
也就是只有宣告會被提升,賦值不會。

變數Hoisting

範例:

console.log(a); // undefined
var a = 5;
console.log(a); // 5
  1. 當用var宣告時,var a會先被提升到作用域的頂端,可以看成以下:
var a;
console.log(a); // undefined
a = 5;
console.log(a); // 5
  1. 第一行的console.log(a)不會報錯,是因為在這階段會為變數保留記憶體空間,初始值為undefined
  2. 第三行a = 5,因為5賦值給變數a了,所以第四行console.log(a)才能印出5

後來有ES6的letconst,兩者變數宣告一樣會提升,但JavaScript確保變數在賦值之前不會被使用
因此變數在賦值之前會進入暫時性死區(TDZ,Temporal Dead Zone)。在TDZ時,變數是不可用的。

MDN關於TDZ暫時性死區的說明:

A variable declared with let, const, or class is said to be in a "temporal dead zone" (TDZ) from the start of the block until code execution reaches the place where the variable is declared and initialized.

把剛剛範例改成let宣告看看:

console.log(a); //  ReferenceError: a is not defined
let a = 5;
console.log(a); // 5
  1. let a = 5 之前,變數a進入了TDZ,因此在第一行console.log(a)會報錯。
  2. a被賦值let a = 5,就能順利印出值了。

函式Hoisting

函式宣告也會被提升,跟變數不一樣的是,函式在提升時,是保留函式整個內容

原先撰寫函式宣告完再執行函式呼叫,在這裡把函式呼叫sayHello()放到程式碼最上方,觀察看看:

sayHello(); // "Hello!"

function sayHello() {
  console.log("Hello!");
}

https://ithelp.ithome.com.tw/upload/images/20240927/20169039MNYtPiNron.png

  1. sayHello()函式呼叫放在函式宣告之前,結果順利印出Hello!
  2. JavaScript會把函式宣告提升到當前作用域的最上方,所以可以看成這樣:
function sayHello() {
  console.log("Hello!");
}

sayHello(); // "Hello!"

所以函式sayHello順利印出"Hello!"

以上分享~謝謝!

參考資料

MDN - Hoisting
MDN - let&TDZ
JS 原力覺醒 Day06 - 提升 Hoisting


上一篇
[Day 12] 運算式與運算子(下) - 優先性與相依性
下一篇
[Day 14] callback function 回呼函式
系列文
JavaScript學習筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言