函数声明会完整提升至作用域顶部,包括函数名和函数体,优先级高于var声明;但函数表达式、let/const声明及块内非标准函数声明均不享受此提升。

函数声明在 JavaScript 中会完整提升到所在作用域的顶部,包括函数名和函数体,且优先级高于 var 变量声明;但这种行为仅适用于标准的函数声明语法(function name() {...}),不适用于函数表达式或 let/const 声明。
函数声明的完整提升机制
JS 引擎在预编译阶段会把函数声明整个“搬”到当前作用域最上方,不只是名字,连函数体也一并提升。这意味着你可以在声明前调用它:
-
foo(); function foo() { console.log('hello'); }→ 正常输出hello - 等价于:
function foo() { console.log('hello'); }; foo(); - 而
var声明只提升变量名,赋值保留在原位,所以console.log(a); var a = 1;输出undefined
函数声明与 var 同名时的优先级规则
当函数声明和 var 声明使用相同标识符时,函数声明先被处理,后续的 var 赋值会覆盖它:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
-
console.log(typeof a); function a() {} var a = 1;→ 输出"function"(函数生效) - 执行到
var a = 1时,a才被重新赋值为1,函数就被覆盖了 - 即使
var写在函数声明前面,如var a; function a() {},结果仍是函数
块级作用域中的函数声明要特别小心
ES6 之前,在 if、for 等块中写函数声明是非标准行为,各浏览器处理不一致;ES6 严格模式下,块内函数声明被视为块级绑定,类似 let:
-
if (true) { function bar() {} } console.log(bar);→ 在严格模式下报ReferenceError - 函数名不会被提升到外层函数或全局作用域
- 建议避免在块内直接写函数声明,改用函数表达式或提前声明到外层
哪些“函数定义”不会被提升?
只有形如 function name() {...} 的语句才算函数声明;其他形式均无完整提升:
-
const fn = function() {}或let fn = () => {}:属于函数表达式 + 块级绑定,处于暂时性死区(TDZ),声明前访问直接报错 -
var fn = function() {}:变量名fn会被提升,但赋值不会,调用时是TypeError: fn is not a function -
function关键字不在行首(如赋值右侧、括号内)→ 全是表达式,不提升
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










