函数声明的提升取决于作用域类型和声明方式:全局和函数作用域中函数声明整体提升,块级作用域中es6严格模式下为块级绑定(tdz),函数表达式仅变量名可能提升,且同名时函数声明优先于var变量声明。

函数声明的提升行为取决于它所在的**作用域类型**和**声明方式**,不是所有函数都会被“完整提升”,也不是所有作用域都表现一致。
全局作用域中的函数声明会整体提升
在全局作用域中,用 function 关键字直接声明 的函数(即函数声明),其整个定义会被提升到作用域顶部,包括函数名和函数体。这意味着可以在声明前调用它:
sayHi(); // 正常输出 "Hello"function sayHi() { console.log("Hello"); }
实际执行时,等价于:
-
function sayHi() { console.log("Hello"); }(提前就绪) sayHi();
函数作用域内的函数声明也提升,但仅限该作用域
在函数内部声明的函数,只会在**该函数的作用域内**被提升,不会泄漏到外部。例如:
outer();function outer() { inner(); function inner() { console.log("inside"); } }
这里 inner 在 outer 内部被提升,所以能正常调用;但若在 outer() 外调用 inner(),会报 ReferenceError —— 因为提升只发生在当前作用域,不跨层。
块级作用域(如 if、for)中函数声明行为不统一
ES5 及更早环境中,在块级结构中使用函数声明属于非标准行为,不同引擎处理方式不同(有的提升到函数作用域顶部,有的仅局部有效)。ES6 起,严格模式下在块中声明函数被视为**块级绑定**,类似 let:
- 函数名不会被提升到外层函数或全局作用域
- 在声明前访问会进入 暂时性死区(TDZ),抛出
ReferenceError - 即使写成
if (true) { function foo() {} },也不能保证foo在块外可用
函数表达式不会被提升,只有变量名可能提升
用 var fn = function() {...} 或 const fn = () => {...} 这类方式定义的函数,本质是**赋值操作**:
-
var声明的变量名会被提升,但赋值不会 → 调用时是TypeError: fn is not a function -
let/const声明的变量名不会提升,且处于 TDZ → 调用时报ReferenceError - 无论哪种,都不能在声明前安全调用
同名声明时,函数声明优先于变量声明
当函数声明与 var 变量声明同名时,函数声明会覆盖变量声明(在提升阶段):
test(); // 输出 "function"var test = "string";function test() { console.log("function"); }
这是因为函数声明提升优先级高于 var 变量声明;但后续赋值仍会覆盖函数,所以 console.log(test) 之后会输出字符串。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











