函数声明在预解析阶段被提升并完整定义,即分配内存存储函数体字符串,支持提前调用;同名时函数覆盖变量;函数表达式仅变量声明提升,不支持提前调用。

函数声明在预解析阶段不仅被提升到作用域顶部,还会完成完整定义——即在内存中开辟空间并存入整个函数体的字符串代码,但此时不执行。
函数声明会分配内存并存储函数体
与 var 变量只声明不赋值不同,function 声明在预解析时就完成了“声明 + 定义”:引擎为其分配一块内存区域,把函数体(包括形参、内部语句等)作为字符串完整存入。这意味着你可以提前调用该函数,而不会报错。
- 例如:
foo(); function foo() { console.log('ok'); }能正常输出,因为预解析后foo已指向一段可执行的函数代码 - 这块内存里存的是函数定义本身,不是执行结果;真正执行要等到调用时
函数优先级高于同名变量
如果同一作用域内存在同名的 var 变量和 function 声明,函数声明会覆盖变量声明——预解析时函数先占位,变量声明被忽略(即使写在函数下方)。
- 如:
console.log(a); var a = 1; function a() {}输出的是函数体,不是undefined - 本质是函数声明的“提升+定义”比变量的“仅声明”更早且更完整
函数内部也会独立预解析
每次函数执行时,都会创建新作用域,并在该作用域内重新进行预解析:参数先被初始化为 undefined,再处理内部的 var 和 function 声明。
- 形参相当于用
var声明的局部变量,会被提升,但初始值来自实参或undefined - 函数内部的函数声明同样会整块存入内存,支持内部提前调用
不适用于函数表达式
只有 function 函数名() {...} 这种声明方式才具备上述特性;用 var fn = function() {...} 或箭头函数时,只是变量声明被提升,赋值(即函数体)仍留在原位置,无法提前调用。
-
bar(); var bar = function() { console.log(1); };会报TypeError: bar is not a function - 因为预解析只做了
var bar;,bar此时是undefined
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











