JavaScript 函数声明在模块内的表现

作者:袖梨 2026-07-08
JavaScript模块中函数声明默认仅限本文件,需用export显式导出、import导入才能跨模块使用;未导出函数不可见、不可用、可能被tree-shaking移除。

JavaScript 函数声明在模块中不是“写完就能用”的独立存在,它默认只在当前文件内有效;要跨模块使用,必须配合 export 显式导出,并由其他模块用 import 正确导入。

函数声明本身不自动对外可见

即使你在模块顶部写了 function utils() { },只要没加 export,这个函数就完全被封装在当前模块作用域里。其他模块无论怎么 import 都拿不到它——这不是限制,而是模块系统的设计原则:天然隔离、按需暴露。

  • 未导出的函数在构建时可能被 tree-shaking 自动移除,节省打包体积
  • import * as mod from './x.js' 也收不到未导出的函数
  • 调试时看不到、类型系统推导不到、IDE 无法补全

导出方式决定外部怎么用

函数声明要共享,得选对导出语法,否则导入方会报错或解构失败:

  • 命名导出:export function formatTime() { } → 导入必须写 import { formatTime } from './x.js'
  • 默认导出:export default function initApp() { } → 导入可任意命名,如 import start from './x.js'
  • 先声明后导出:function helper() { } + export { helper },适合需要复用或条件导出的场景

不能在块级作用域里声明再导出

if (true) { export function foo() { } } 这种写法是语法错误。export 必须出现在模块顶层作用域,不能嵌套在条件、循环或函数内部。

立即学习“Java免费学习笔记(深入)”;

  • 函数声明可以提升,但 export 是静态解析,不支持动态逻辑
  • 想按条件提供不同函数?改用导出对象或工厂函数,比如 export const api = isProd ? prodApi : devApi
  • 浏览器和打包工具都会直接报错,别依赖非标准行为

模块执行顺序影响函数可用时机

函数声明在本模块内会被提升,但它的“可用性”取决于整个模块是否已执行完毕。如果 A 模块导入 B 模块,B 中的函数声明一定先于 A 中的任何调用生效。

  • 不要在模块顶层直接调用依赖其他模块的状态函数(比如 initConfig()),避免执行顺序错乱
  • 推荐把初始化逻辑封装成导出函数,由调用方按需触发,而不是靠模块加载自动执行
  • 异步加载(import())会打破同步执行链,此时函数定义可能尚未就绪

相关文章

精彩推荐