var声明仅提升声明(值为undefined),函数声明整体提升可提前调用;两者均遵循函数作用域,块级语句不产生新作用域;let/const无变量提升,存在暂时性死区。

JavaScript 中的作用域和变量提升是紧密关联的两个机制。作用域决定了变量和函数在哪里可被访问,而变量提升则描述了它们在作用域内“提前可用”的方式——但这种“提前”仅限于声明,不等于赋值或初始化。
var 声明:只提升声明,值为 undefined
使用 var 声明的变量,其声明会被提升到当前函数作用域(或全局作用域)顶部,但赋值保留在原位置。因此,在声明前访问该变量不会报错,而是返回 undefined。
- 引擎实际处理逻辑等价于:
var a;被移到作用域开头,a = 10;仍在原处 - 即使在
if或for块中用var声明,它也属于整个函数作用域,不是块级作用域 - 重复的
var声明会被忽略,不会报错
函数声明:整体提升,可提前调用
function 函数名() {} 这种函数声明,整个函数定义(包括函数体)都会被提升到作用域顶部。因此可以在声明之前安全调用。
- 例如:
foo(); function foo() { console.log('ok'); }可正常执行 - 如果同名标识符既有函数声明又有
var声明,函数声明优先级更高,会先被提升;但后续的var赋值仍会覆盖函数值 - 注意:函数表达式(如
var bar = function() {})按var规则处理,只提升var bar,不提升函数本身
作用域如何影响提升范围
提升始终发生在**当前作用域内**,而不是全局或任意位置:
立即学习“Java免费学习笔记(深入)”;
-
var和函数声明都遵循**函数作用域**:在函数内部声明,就只提升到该函数顶部;在全局声明,则提升到全局作用域顶部 - 块语句(如
if、for)不创建新作用域,因此其中的var仍属于外层函数或全局作用域 - ES6 引入的
let/const是块级作用域,且不真正提升(存在暂时性死区),这与var和函数声明形成关键对比
为什么理解这个很重要
变量提升不是语法糖,而是 JavaScript 执行模型的一部分——V8 等引擎在编译阶段扫描并预处理声明。若忽略这一机制,容易写出看似合理却行为异常的代码,比如:
- 在函数开头读取一个后面才
var声明的变量,得到undefined而非报错 - 误以为
if块里声明的var是局部的,结果它污染了整个函数作用域 - 混淆函数声明与函数表达式的提升差异,导致调用失败


















