JavaScript变量提升指声明被提升至作用域顶部,但赋值不提升;var声明提升并初始化为undefined,let/const存在暂时性死区,函数声明完全提升而函数表达式仅变量声明提升。

JavaScript变量提升(Hoisting)是指在代码执行前,JavaScript引擎会把变量和函数的声明“提升”到当前作用域顶部的行为。注意,只有声明被提升,赋值不会被提升。
变量提升只提升声明,不提升赋值
使用 var 声明的变量,会被提升到作用域顶部,并初始化为 undefined;而 let 和 const 虽然也存在声明提升,但它们处于“暂时性死区”(TDZ),在声明前访问会直接报错(ReferenceError)。
- var a = 10; 等价于先 var a;(提升),再 a = 10;(赋值)
- console.log(a); var a = 10; 输出 undefined,不是报错
- console.log(b); let b = 20; 直接抛出 ReferenceError
函数声明会被完全提升,函数表达式不会
函数声明(function foo() {...})会被完整提升,包括函数体,因此可以在声明前调用;而函数表达式(var foo = function() {...})只是变量声明被提升,赋值仍保留在原位置。
- foo(); function foo() { console.log('ok'); } 正常输出 'ok'
- bar(); var bar = function() { console.log('no'); }; 报错:TypeError: bar is not a function(因为 bar 被提升为 undefined)
不同声明方式的影响对比
现代开发中推荐优先使用 const 和 let,它们更符合直觉、减少意外行为。
立即学习“Java免费学习笔记(深入)”;
- var:变量可重复声明,存在变量提升 + 初始化为 undefined,易引发静默 bug
- let:块级作用域,声明提升但不可访问(TDZ),禁止重复声明
- const:同 let,且必须初始化,赋值后不可重新赋值(引用类型可改内部属性)
如何避免变量提升带来的问题
养成良好的声明习惯,能大幅降低由提升引发的困惑和错误。
- 所有变量和函数尽量在作用域开头统一声明(尤其用 var 时)
- 优先使用 const,需要重新赋值再用 let,避免 var
- 函数尽量用声明形式(如需条件定义,可用立即执行函数或 if/else 分支)
- 借助 ESLint 规则(如 no-use-before-define)提前发现潜在问题
基本上就这些。理解提升不是为了记住特例,而是看清 JS 执行逻辑的底层节奏——它不改变代码顺序,但会影响“可访问性”。写清楚、声明靠前、选对关键字,问题自然少很多。











