JavaScript模块中的函数声明默认只在本文件内生效,必须通过export导出才能被其他模块导入使用。未导出的函数可能被tree-shaking移除,且不能通过块级作用域导出。模块执行顺序影响函数可用时机,异步加载可能打破同步执行链。
JavaScript模块中函数声明的行为解析
作者:技术拾光
时间:2026-07-26
浏览:208
文章目录
模块中的函数声明,远比你想象的“内向”
JavaScript 模块里的函数声明,默认只在本文件内生效。想跨模块共享?必须走 export 导出、import 导入这套流程。不导出的话,其他模块根本拿不到,甚至打包时 tree-shaking 都可能直接把它清理掉 —— 这可不是 Bug,而是模块系统的设计哲学:天然隔离,按需暴露。

函数声明本身不自动对外可见
哪怕你在模块顶部写了 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 必须出现在模块顶层作用域,不能嵌套在条件、循环或函数内部。
- 函数声明可以提升,但
export是静态解析,不支持动态逻辑 - 想按条件提供不同函数?改用导出对象或工厂函数,比如
export const api = isProd prodApi : devApi - 浏览器和打包工具都会直接报错,别依赖非标准行为
模块执行顺序影响函数可用时机
函数声明在本模块内会被提升,但它的“可用性”取决于整个模块是否已执行完毕。如果 A 模块导入 B 模块,B 中的函数声明一定先于 A 中的任何调用生效。
- 不要在模块顶层直接调用依赖其他模块的状态函数(比如
initConfig()),避免执行顺序错乱 - 推荐把初始化逻辑封装成导出函数,由调用方按需触发,而不是靠模块加载自动执行
- 异步加载(
import())会打破同步执行链,此时函数定义可能尚未就绪
实用工具推荐
电子包浆
使用 ›绿化、压缩、噪点和虚拟水印,自由调节做旧程度。
图片压缩
使用 ›选择画质和输出格式,预览压缩前后的大小。
相关文章