函数声明在模块中默认不可见,仅当显式用export导出时才对外可用;命名导出需按名导入,default导出可任意命名;未导出函数被tree-shaking移除,且不应为调试导出内部细节。

函数声明在模块化导出时的可见性,取决于它是否被显式导出,以及导出方式是否匹配调用方的导入语法。模块本身天然隔离作用域,未导出的函数对外完全不可见——这不是约定,而是语言机制强制保障的封装边界。
模块内函数默认不可访问
在 ES6 模块中,所有顶层声明(包括 function、const、let、class)都只在当前模块作用域内有效。即使函数写在文件顶部,只要没用 export 标记,外部就无法通过任何 import 语法拿到它。
- 例如:
function helper() { return 'internal'; }不导出 → 其他模块 import 后查不到这个名 - 即便用
import * as utils from './math.js',helper也不会出现在utils对象里 - 这种隐藏是静态的:打包工具(如 Vite、Webpack)在构建时就能确认它未被引用,可安全移除(tree-shaking)
命名导出决定调用方如何使用
只有加了 export 前缀的函数声明,才构成对外接口。命名导出要求调用方必须用对应名称解构导入,名字必须一致(或显式重命名)。
-
export function add(a, b) { return a + b; }→ 必须import { add } from './math.js' - 支持导出时改名:
export { add as sum }→ 调用方用{ sum }接收 - 多个命名导出便于按需加载,也利于类型推导和 IDE 自动补全
默认导出仅限一个,且不依赖名称匹配
用 export default 导出函数时,模块对外只暴露一个“主入口”,导入方可以任意起名,无需关心原函数名。
立即学习“Java免费学习笔记(深入)”;
-
export default function createLogger() { ... }→ 可以import logger from './logger.js'或import makeLog from './logger.js' - 默认导出适合单一职责模块(比如一个工厂、一个配置生成器),但不能和命名导出混用同一名字
- 注意:默认导出的是函数表达式或箭头函数时,函数名不可被外部读取(匿名),调试栈中可能显示
default
避免导出内部实现细节
导出函数不是目的,提供稳定、语义清晰的接口才是。不要为“方便测试”或“临时调试”而导出辅助函数,这会污染模块契约。
- 错误做法:
export function _validateEmail() { ... }(下划线不阻止访问,只是弱提示) - 正确做法:把校验逻辑写在闭包内或私有变量中,只导出
registerUser这类业务方法 - 若真需暴露底层能力,应单独拆成新模块,而不是在一个模块里堆砌所有函数


















