最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
怎样用函数声明定义具名函数并理解其变量提升特性
时间:2026-06-25 09:09:52 编辑:袖梨 来源:一聚教程网
函数声明完整提升至作用域顶部,可声明前调用;var变量仅声明提升、初始化不提升;同名时函数声明优先于var声明且不被覆盖。
函数声明会提升,但只提升函数名和函数体
函数声明(function foo() {})在 JavaScript 中会被「提升」到当前作用域顶部,意味着你可以在声明前调用它。但注意:只有整个函数定义被提升,不是执行顺序提前,也不是变量赋值式地“运行”了函数。
常见错误是以为 console.log(foo) 在声明前会输出 undefined —— 实际上它输出的是函数对象本身。这是因为提升的是函数定义,而非类似 var 那样的“声明+初始化分离”行为。
-
foo()在声明前能正常执行(如foo(); function foo() { console.log('hi'); }) -
typeof foo在声明前是"function",不是"undefined" - 如果同名标识符既有函数声明又有
var声明(如var foo; function foo() {}),函数声明仍优先被提升,var声明不会覆盖它
别和函数表达式混淆:const/let 声明的函数不提升
写成 const foo = function() {} 或 const foo = () => {} 是函数表达式,受 const/let 的「暂时性死区(TDZ)」约束——访问未初始化的绑定会直接抛出 ReferenceError,而不是返回 undefined。
这跟 var foo = function() {} 也不同:var 版本会提升声明(foo 变量名存在),但初始化(赋值)留在原地,所以声明前读取 foo 得到 undefined,调用会报 TypeError: foo is not a function。
- 函数声明:
foo()✅ 声明前可调用 -
var foo = function() {}:foo()❌ 报TypeError;console.log(foo)→undefined -
const foo = function() {}:foo()❌ 报ReferenceError(进入作用域但未初始化)
嵌套函数声明的提升范围仅限于所在函数作用域
在函数内部用 function bar() {} 声明,这个 bar 只会在该外层函数体内被提升,对外不可见,也不会污染外层作用域。
容易踩的坑是误以为嵌套声明会提升到全局——它不会。而且不同浏览器对块级函数声明(比如写在 if 块里)的行为曾有分歧(ES2015 后统一为「仅在块内提升,且具有块级作用域」),但主流环境现在都按标准处理。
- 在
function outer() { function inner() {} inner(); }中,inner()可以在声明前调用 - 但在
outer()外部调用inner()会报ReferenceError - 避免在非严格模式下依赖块级函数声明,严格模式下它等价于
let声明(即 TDZ 行为)
实际开发中该选函数声明还是函数表达式?
函数声明适合定义逻辑清晰、需提前使用的工具函数(如递归主入口、事件处理器骨架),尤其在模块顶层或立即执行上下文中;函数表达式更常用于需要控制作用域、延迟初始化、或作为参数传递的场景。
真正容易被忽略的是:函数声明的提升无法跨文件、无法跨 eval 或动态 import() 边界。也就是说,如果你把 function foo() {} 放在一个异步加载的脚本里,它不会“提前”影响当前执行流中的代码。
- 模块内顶层函数声明可安全前置调用,但不要指望它能在
import语句之前生效 - 使用构建工具(如 Webpack/Vite)时,提升行为仍以单个 JS 文件为单位,不跨打包产物边界
- TS 编译后是否保留提升取决于
target设置(ES5保持,ES6+一般也保持,但类型擦除不影响运行时行为)
相关文章
- 百度智能云官网入口 - 企业AI云计算服务平台 06-27
- PayMob支付平台官网入口 - 2026最新国际支付解决方案 06-27
- 粉笔教育官网入口 - 在线备考学习平台 06-27
- 未来网官网入口及功能介绍 - 2026最新版 06-27
- 信发集团官网入口 - 2026年最新企业信息查询 06-27
- 兔展官网入口 - 专业H5互动营销平台 06-27