鲁斯前端布鲁斯前端

文章中英模式

布鲁斯前端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 限定的是变量绑定不可重新赋值,但对象内容仍可修改。