魯斯前端布魯斯前端

文章中英模式

布魯斯前端JS面試題目 - 變數 const、let、var 與 Hoisting

理解 JavaScript 中變數宣告方式與執行時期的內部機制。

影片縮圖

懶得看文章?那就來看影片吧

為什麼使用 const / let / var?

關鍵字可重新賦值可重新宣告作用域用途建議
var函式作用域不建議使用
let區塊作用域可變資料
const區塊作用域常數、函式定義

Hoisting 原理與 TDZ(暫時性死區)

JavaScript 在執行前會將變數與函式的宣告「提升」至作用域最上方。

var 宣告會被提升並初始化為 undefined

let const 被提升但不初始化,進入 TDZ

TDZ(暫時性死區)是變數不能被存取的期間

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

console.log(b); // ReferenceError
let b = 10;

console.log(c); // ReferenceError
const c = 10;

function 宣告 vs const function 表達式

只有 function 宣告會被完整提升;const 宣告的函式表達式不會被提升。

類型是否提升能否先呼叫
function 宣告
const function 表達式
foo(); // 正常執行
function foo() {
  console.log("function declaration");
}

bar(); // ReferenceError
const bar = function () {
  console.log("function expression");
};

🔥 常見面試題目

(一)解釋 Hoisting

解答: Hoisting 就是 JavaScript 在執行前,會先把變數或函式的「宣告」偷偷搬到最上面,像是這樣:

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

console.log(b); // ReferenceError
let b = 10;

console.log(c); // ReferenceError
const c = 10;

所以說,var 宣告的變數會被提升並初始化為 undefined,而 let 和 const 也會「被提升」,只是進入 TDZ(暫時性死區)尚未初始化,所以會報錯 ReferenceError。

(二)下列哪一段會執行成功?為什麼?

foo();
function foo() {
  console.log('foo');
}

bar();
const bar = function () {
  console.log('bar');
};

解答:foo 是 function 宣告,會被提升並可在宣告前使用;bar 是 const 函式表達式,不會提升,會拋出 ReferenceError。

(三)這段程式碼是否會錯?為什麼?

const person = { name: 'Alice' };
person.name = 'Bob';

解答:不會錯。const 限定的是變數綁定不可重新賦值,但物件內容仍可修改。