JavaScript面試考題:Hoisting是什麼?

更新 發佈閱讀 6 分鐘

在JS中很重要的觀念就是hoisting,中文叫做「提升」。先來看看以下程式碼:

var a ='Hello World!'

function b(){
console.log('Called b!')
}

b();
console.log(a)

可想而知會印出:

//Called b!
//Hello World!

那如果將b()和console.log(a)放到程式碼前面呢?

b();
console.log(a)

var a ='Hello World!'

function b(){
console.log('Called b!')
}

JS都是逐行逐行執行的,照理來說函式b沒有被宣告就被執行,應該會報錯,但事實不然,b()跟console.log(a)都不會報錯,b()會執行程式,a則會報個undefined:

//Called b!
//undefined
這是因為hoisting

網路解釋的hoisting

比較常看到的解釋是說hoisting會在執行時,把變數和函式提升到程式碼的頂部:

function b(){
console.log('Called b!')
}
var a;

b();
console.log(a)

var a ='Hello World!'

而變數又比較不一樣,它只會提升var a ,不會提升後面的值’Hello World!’,於是JavaScript 全攻略:克服 JS 的奇怪部分的老師Anthony Alicea提出不同的觀念想法,我覺得也蠻好記的。

Anthony Alicea的hoisting

首先我們必須先明白,電腦並不是直接執行我們寫的JS code,而是透過一個轉譯器「syntax parser 語法解析器」來檢查我們寫的程式碼,並轉譯成電腦懂的語言讓電腦去執行。

轉譯給電腦後,JS會製造出一個execution context執行環境,被執行的程式碼會被包起來裝在執行環境中,而執行環境分為兩個階段:

  1. Creation Phase 創造階段
  2. Execution Phase 執行階段

在Creation Phase時,JS會自動幫變數和函式製造出記憶體空間,所以在執行前,JS已經知道有這個變數a還有函式b()。

但在執行前,JS只知道有這個變數a,還不知道a的值是多少,設值是執行後才會知道的,所以JS會給undefined這個預設值。

Creation Phase 創造階段

JS:哦哦我知道有a這個變數,也知道b這個函式!b要執行的是console.log(‘Called b!’),但我還不知道a會是多少,而a的預設值是undefined。

b();
console.log(a)

var a ='Hello World!'

function b(){
console.log('Called b!')
}

// Called b!
// undefined

Execution Phase 執行階段

JS:我知道a是多少了!!是Hello World!

b();
console.log(a)

var a ='Hello World!'

function b(){
console.log('Called b!')
}

console.log(a)

// Called b!
// undefined
// Hello World!

沒宣告就執行→還是會報錯

b();
console.log(a)

function b(){
console.log('Called b!')
}

//Called b!
//Uncaught ReferenceError: a is not defined

因為根本沒有宣告a,JS的記憶體中沒有a這個變數。

undefined跟ReferenceError: a is not defined 有何不同?

undefined:代表這個值還沒被設定,而undefined是JS中特殊的值(value)

var a;
console.log(a)

if(a === undefined){
console.log('a is undefined')
}else{
console.log('a is defined')
}

// undefined
// a is undefined
a === undefined

如果沒有var a;

console.log(a)

if(a === undefined){
console.log('a is undefined')
}else{
console.log('a is defined')
}

// Uncaught ReferenceError: a is not defined

因為JS在記憶體中找不到a,所以就會報錯。

undefined是JS中特殊的value。

老師建議沒事不要把執行放在宣告前,很容易搞錯,還是按照順序就好嚕;

var a ='Hello World!'

function b(){
console.log('Called b!')
}

console.log(a)
b()

// Hello World!
// Called b!

至於要用網路上廣泛的解釋方式還是老師的解釋,我是覺得沒差,反正知道結果就好了。

參考資料:
JavaScript 全攻略:克服 JS 的奇怪部分

留言
avatar-img
溫蒂蒂蒂的沙龍
2會員
2內容數
前端筆記希望不要再鬼打牆
你可能也想看
Thumbnail
提升(Hoisting) 指的是在創造環境階段時就把變數準備好,這時值還沒被賦予到變數上。此類型的概念可以使用執行環境的「創造階段」與「執行階段」來理解。
Thumbnail
提升(Hoisting) 指的是在創造環境階段時就把變數準備好,這時值還沒被賦予到變數上。此類型的概念可以使用執行環境的「創造階段」與「執行階段」來理解。
Thumbnail
什麼是提升?在 JavaScript 中,提升是指變數和函數宣告會在程式執行前被「提升」到它們所在作用域(scope)的頂部。這是 JavaScript 引擎處理程式碼時的一種行為,讓你在宣告之前就能使用某些變數或函數。
Thumbnail
什麼是提升?在 JavaScript 中,提升是指變數和函數宣告會在程式執行前被「提升」到它們所在作用域(scope)的頂部。這是 JavaScript 引擎處理程式碼時的一種行為,讓你在宣告之前就能使用某些變數或函數。
Thumbnail
在JS中很重要的觀念就是hoisting,中文叫做「提升」
Thumbnail
在JS中很重要的觀念就是hoisting,中文叫做「提升」
Thumbnail
Hoisting 可以說是 ES6 問世之後,去面試還是會爾偶被問到的面試考題,雖然 Hoisting 離 Modern JavaScript 的技術有點距離,實作上幾乎不太會用到,但透過了解 Hoisting 的概念,可以對這門語言有更深的了解與掌握度。
Thumbnail
Hoisting 可以說是 ES6 問世之後,去面試還是會爾偶被問到的面試考題,雖然 Hoisting 離 Modern JavaScript 的技術有點距離,實作上幾乎不太會用到,但透過了解 Hoisting 的概念,可以對這門語言有更深的了解與掌握度。
Thumbnail
auto(自動)、register(暫存器)、static(靜態)、extern(外部),以作用範圍(scope)、存儲時期(life time)、連結(linkage)的不同作為區別。
Thumbnail
auto(自動)、register(暫存器)、static(靜態)、extern(外部),以作用範圍(scope)、存儲時期(life time)、連結(linkage)的不同作為區別。
Thumbnail
這是一場修復文化與重建精神的儀式,觀眾不需要完全看懂《遊林驚夢:巧遇Hagay》,但你能感受心與土地團聚的渴望,也不急著在此處釐清或定義什麼,但你的在場感受,就是一條線索,關於如何找著自己的路徑、自己的聲音。
Thumbnail
這是一場修復文化與重建精神的儀式,觀眾不需要完全看懂《遊林驚夢:巧遇Hagay》,但你能感受心與土地團聚的渴望,也不急著在此處釐清或定義什麼,但你的在場感受,就是一條線索,關於如何找著自己的路徑、自己的聲音。
Thumbnail
背景:從冷門配角到市場主線,算力與電力被重新定價   小P從2008進入股市,每一個時期的投資亮點都不同,記得2009蘋果手機剛上市,當時蘋果只要在媒體上提到哪一間供應鏈,隔天股價就有驚人的表現,當時光學鏡頭非常熱門,因為手機第一次搭上鏡頭可以拍照,也造就傳統相機廠的殞落,如今手機已經全面普及,題
Thumbnail
背景:從冷門配角到市場主線,算力與電力被重新定價   小P從2008進入股市,每一個時期的投資亮點都不同,記得2009蘋果手機剛上市,當時蘋果只要在媒體上提到哪一間供應鏈,隔天股價就有驚人的表現,當時光學鏡頭非常熱門,因為手機第一次搭上鏡頭可以拍照,也造就傳統相機廠的殞落,如今手機已經全面普及,題
Thumbnail
本文分析導演巴里・柯斯基(Barrie Kosky)如何運用極簡的舞臺配置,將布萊希特(Bertolt Brecht)的「疏離效果」轉化為視覺奇觀與黑色幽默,探討《三便士歌劇》在當代劇場中的新詮釋,並藉由舞臺、燈光、服裝、音樂等多方面,分析該作如何在保留批判核心的同時,觸及觀眾的觀看位置與人性幽微。
Thumbnail
本文分析導演巴里・柯斯基(Barrie Kosky)如何運用極簡的舞臺配置,將布萊希特(Bertolt Brecht)的「疏離效果」轉化為視覺奇觀與黑色幽默,探討《三便士歌劇》在當代劇場中的新詮釋,並藉由舞臺、燈光、服裝、音樂等多方面,分析該作如何在保留批判核心的同時,觸及觀眾的觀看位置與人性幽微。
Thumbnail
JavaScript在ES6新增了let, const等宣告變數的方式,其中let, const是block scope的,而var則是function scope。
Thumbnail
JavaScript在ES6新增了let, const等宣告變數的方式,其中let, const是block scope的,而var則是function scope。
Thumbnail
執行以上程式碼,然後看到了這個結果: 為什麼「延遲0秒」的函式寫在上方,但在console印出的結果,它還是被排在第二順位? 利用AC教材提供的youtube演講連結一窺究竟: 演講提供了更多JS的細節概念,身為JS新手的我還在消化,但若針對教案提出的問題來回答,加上利用google大神查到MDN的
Thumbnail
執行以上程式碼,然後看到了這個結果: 為什麼「延遲0秒」的函式寫在上方,但在console印出的結果,它還是被排在第二順位? 利用AC教材提供的youtube演講連結一窺究竟: 演講提供了更多JS的細節概念,身為JS新手的我還在消化,但若針對教案提出的問題來回答,加上利用google大神查到MDN的
Thumbnail
前言 這是第一次寫技術文章,但其實應該也只能說是蒐集很多資料並學習如何透過自己的話解釋的內容,並不能像其他大神可能分享一些很酷的技術,目標就單純是為了完成最後一週的作業(如下)。 走入非同步之前 執行環境(Execution Context) 執行環境堆疊 (Execution stack)
Thumbnail
前言 這是第一次寫技術文章,但其實應該也只能說是蒐集很多資料並學習如何透過自己的話解釋的內容,並不能像其他大神可能分享一些很酷的技術,目標就單純是為了完成最後一週的作業(如下)。 走入非同步之前 執行環境(Execution Context) 執行環境堆疊 (Execution stack)
Thumbnail
5 月將於臺北表演藝術中心映演的「2026 北藝嚴選」《海妲・蓋柏樂》,由臺灣劇團「晃晃跨幅町」製作,本文將以從舞台符號、聲音與表演調度切入,討論海妲・蓋柏樂在父權社會結構下的困境,並結合榮格心理學與馮.法蘭茲對「阿尼姆斯」與「永恆少年」原型的分析,理解女人何以走向精神性的操控、毀滅與死亡。
Thumbnail
5 月將於臺北表演藝術中心映演的「2026 北藝嚴選」《海妲・蓋柏樂》,由臺灣劇團「晃晃跨幅町」製作,本文將以從舞台符號、聲音與表演調度切入,討論海妲・蓋柏樂在父權社會結構下的困境,並結合榮格心理學與馮.法蘭茲對「阿尼姆斯」與「永恆少年」原型的分析,理解女人何以走向精神性的操控、毀滅與死亡。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News