iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 29
1
自我挑戰組

前端菜焦阿日記系列 第 29

|D29| JS - 原來我不懂 hoisting

tags: 2019年鐵人賽

前言

拜讀到這篇我知道你懂 hoisting,可是你了解到多深?
,精闢的解釋又了解更多對 hoisting 的觀念,藉著這篇的分析邏輯做一下筆記。

什麼是 hoisting?

下面這段程式會出錯,是因為第一行 a 尚未被宣告,代表找不到記憶體位置

console.log(a); //Uncaught ReferenceError: a is not defined

但為何這段程式卻顯示 undefined 呢?

console.log(a); //undefined
var a = 2;

因為 a 被提升到 log 前宣告了!

1. 對 var 而言只有「宣告」會 hoisting

JS 對 var 會做兩個動作

  • 宣告,只有「宣告」會 hoisting
  • 賦值
//範例1
console.log(a); //undefined
var a = 2;

//把範例1想像成下面執行過程
var a; //宣告提升
console.log(a); //undefined
a = 2; //賦值

//範例2
var b = 10;
var b;
console.log(b); //10,不要以為 b 重新賦值為 undefined

//把範例2想像成下面執行過程
var b; //宣告提升
var b;
b = 10;
console.log(b); //10

2. 對 function 而言優先級比 var 高

console.log(x); //f x(){}
var x = 1;
function x(){}

3. 對 let 跟 const 而言

本來以為不會有 hoisting

console.log(a); //Uncaught ReferenceError: a is not defined
let a = 2;

直到看到文章提的範例

var a = 10;
function test(){
  console.log(a);
  let a;
}
test();

我以為 log 結果是 10 ,會找全域變數的 a
居然是
Uncaught ReferenceError: a is not defined

Uncaught ReferenceError: a is not defined

Uncaught ReferenceError: a is not defined

表示說 let 的確有被 hoisting,只是給的反應與 var 不同

回頭看看 var,var 在提升後會給初始值 undefined,所以 log 才會是undefined

//範例
console.log(a); //undefined
var a = 1;

//把範例想像成下面執行過程
var a; //提升後會給初始值 undefined
console.log(a); //undefined
a = 1;

let 與 const 在「提升後」,和「賦值之前」,存在一個區間叫 Temporal Dead Zone (TDZ),在「賦值之前」存取它就會拋出錯誤。

//範例
console.log(a); //undefined
let a = 1;

//把範例想像成下面執行過程
let a; //提升後不會給初始值 undefined,也是 TDZ 的開始
console.log(a); //Uncaught ReferenceError: a is not defined,因為在賦值之前,所以拋出錯誤

上一篇
|D28| JS - function statement(陳述式)和expression(表達式)
下一篇
|D30| 前端菜焦阿日記系列 - 總目錄
系列文
前端菜焦阿日記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言