函数声明提升优先级高于var变量声明,即函数声明会完整提升至作用域顶部并赋值,而var仅提升声明、初始值为undefined;同名时函数声明先绑定,后续var赋值会覆盖该绑定;let/const不适用此规则,函数表达式仅var部分提升。

函数声明的提升优先级高于 var 变量声明,这是 JavaScript 执行上下文预编译阶段的关键规则。理解它,核心不是记顺序,而是看“谁先在作用域中绑定值”。
函数声明会完整提升,变量声明只提升声明
函数声明(function foo() {})在预编译阶段就被整个搬到了作用域顶部,包括函数体;而 var foo 只是把声明提前,赋值仍留在原地,初始值为 undefined。
- 这意味着即使 var foo 写在函数声明前面,函数定义依然会先“生效”
- 例如:console.log(foo) 会输出函数,而不是 undefined
同名时,函数声明覆盖变量声明,但不抵抗赋值
当函数和 var 变量同名,JS 引擎不会重复创建标识符,而是复用同一个绑定。函数声明先完成赋值,后续的 var foo = ... 不是重新声明,而是对已有绑定的赋值操作。
- 所以第一次访问看到的是函数,第二次赋值后就变成新值(比如数字、字符串等)
- 注意:let/const 不适用此规则——它们有暂时性死区,同名函数声明 + let a 会导致运行时报错
实际执行过程可简化为三步
以这段代码为例:
console.log(a);
var a = 1;
function a() { console.log(2); }
- 预编译:先绑定 a = function a() { console.log(2); }
- 执行第一行:输出该函数
- 执行到 var a = 1:不是重声明,而是把 a 的值改为 1
函数表达式不享受高优先级
像 var b = function() {} 这类写法,本质是变量声明 + 赋值,只有 var b 被提升,函数本身不会提前可用。
- 它和普通 var 行为一致:声明提升,赋值不提升
- 因此不能在声明前调用,否则报 TypeError: b is not a function

















