JavaScript 中的 hoisting 是声明在编译阶段被提前注册而非代码上移,var 初始化为 undefined,let/const 进入 TDZ 访问即报错,函数声明完全提升而表达式仅提升变量名。

JavaScript 中的 hoisting 不是“把代码往上挪”,而是变量和函数声明在编译阶段被提前“注册”到当前作用域中,但赋值行为仍保留在原地。这意味着 var 声明的变量会初始化为 undefined,而 let/const 声明则进入“暂时性死区”(TDZ),访问会直接报错。
var 声明为何能访问但值是 undefined
var 的 hoisting 包含声明 + 初始化(默认为 undefined),但不包括赋值。所以即使在声明前读取,也不会报错,只是拿到一个无意义的初始值。
- 常见错误现象:
console.log(a); var a = 1;输出undefined,而非ReferenceError或1 - 实际执行逻辑等价于:
var a; console.log(a); a = 1; - 函数内重复
var a不会报错,只会被忽略——多次声明等同于一次
let/const 在 TDZ 中访问会立即报错
let 和 const 声明会被 hoist,但不会初始化;从作用域头部到声明语句之间这段区域就是 TDZ。在此区域内访问变量,JS 引擎抛出 ReferenceError。
- 错误示例:
console.log(b); let b = 2;→ 报错ReferenceError: Cannot access 'b' before initialization -
const还额外要求必须在声明时赋值,否则语法错误:const c;直接无法通过解析 - TDZ 不仅影响
console.log,也影响typeof:typeof d在声明前也会触发 ReferenceError
函数声明 vs 函数表达式 hoisting 行为完全不同
函数声明(function foo() {})完整 hoist:声明 + 定义都提前;函数表达式(var bar = function() {})只 hoist 变量名,不 hoist 赋值,因此不能在定义前调用。
无论从何种情形出发,在目前校长负责制的制度安排下,中小学校长作为学校的领导者、管理者和教育者,其管理水平对于学校发展的重要性都是不言而喻的。从这个角度看,建立科学的校长绩效评价体系以及拥有相对应的评估手段和工具,有利于教育行政机关针对校长的管理实践全过程及其结果进行测定与衡量,做出价值判断和评估,从而有利于强化学校教学管理,提升教学质量,并衍生带来校长转变管理观念,提升自身综合管理素质。
立即学习“Java免费学习笔记(深入)”;
- 可安全调用:
foo(); // OK function foo() { return 'hoisted'; } - 不可调用,报
TypeError:bar(); // TypeError: bar is not a function var bar = function() { return 'not hoisted'; }; - 箭头函数属于函数表达式,同样不具函数声明级 hoisting
class 声明也受 TDZ 约束,且不能被重复声明
class 在语法上更接近 let:声明会被 hoist,但未到声明位置前访问会报 ReferenceError;且不允许重复声明,哪怕用 var 也不行。
- 错误示例:
new MyClass(); // ReferenceError class MyClass {} - 即使尝试覆盖:
var MyClass = 42; class MyClass {}→ SyntaxError(Identifier 'MyClass' has already been declared) - 继承时父类也必须已定义,
class Child extends Parent中Parent必须在Child声明前完成初始化
最容易被忽略的是 TDZ 的边界并不总等于大括号块——它由词法环境创建时机决定,比如 for (let i...) 中每个迭代都有独立 TDZ,而 var i 则共享同一个变量。实际写代码时,别依赖 hoisting 去“提前用”,老老实实把声明放在使用之前最稳妥。










