变量提升是JavaScript引擎编译阶段将var和函数声明登记到作用域,而非代码移动;var只提升声明(值为undefined),函数声明整体提升,let/const提升但处于TDZ中访问报错。

变量提升(Hoisting)不是代码被“移动”了,而是 JavaScript 引擎在执行前先做一次编译扫描,把 var 和函数声明登记到当前作用域中。声明存在,但赋值仍在原处——所以能访问变量却不报错,却拿到 undefined。理解这点,就能避开大多数坑。
var 声明:只提声明,不提赋值
var 的提升表现很明确:变量名被提前登记,初始值为 undefined,赋值语句不动。
- 写在
console.log(a)后面的var a = 10,实际等效于先有var a(顶部),再执行a = 10(原位置) - 函数内用
var声明同名变量,会遮蔽外层变量,哪怕声明写在console.log后面,前面访问也得到undefined - 全局
var变量会自动挂到window上(浏览器环境)
函数声明 vs 函数表达式
函数声明整体提升,函数表达式只提升变量名。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
foo()可以在function foo() {}之前调用,因为整个函数体被提升了 -
bar()写在var bar = function() {}前会报TypeError: bar is not a function,因为只有bar变量被提升,值为undefined - 如果同时存在
var foo和function foo() {},函数声明优先,foo指向函数
let/const:有提升,但进 TDZ 就报错
let 和 const 也会提升声明,但不会初始化;从作用域开头到声明语句之间是“暂时性死区(TDZ)”。
立即学习“Java免费学习笔记(深入)”;
- 在 TDZ 中访问变量,直接抛
ReferenceError,不是undefined - 这其实是更严格的约束,强制按顺序声明再使用
- 块级作用域(如
if、for内)中用let/const,变量只在该块内有效
实用规避方式
不靠绕开机制,而靠习惯降低风险:
- 新项目默认用
let和const,避免var的遮蔽和隐式提升混淆 - 函数内部若仍用
var,统一放在函数顶部声明(可加注释说明意图) - 避免内外层同名变量,尤其别在函数里重新声明全局变量名
- 启用严格模式(
"use strict"),让一些隐式错误更早暴露

















