前端进阶之旅前端进阶之旅
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
首页程序员面试题库ESM named export vs default export
JSJavaScript模块与语言机制

ESM 中具名导出与默认导出的主要区别是什么,什么时候该用默认导出?

ESM 具名导出要求导入端使用 {} 列出名称(可as改名),默认导出可被任意标识符接收。单值、入口性功能适合默认导出;成组 API 用具名导出,便于静态分析。

前端进阶之旅 · 一题精讲更新于 2026.09.05
JavaScript#模块与语言机制
先看核心答案
理解线索

从命名权看两种导出

  1. 语法入口具名用括号,默认用任意名称
  2. 数量一个模块最多一个默认
  3. 语义具名表多入口,默认表主值

优先按接口是单主值还是多 API 做决定。

核心回答

先记住这个答案

具名导出将模块内变量标记为可外部引用,导入需在花括号内列举其名称(可用 as 改名),例如 import { format } from './m.js';默认导出导出的值是模块直接视为“主值”,导入写成 import fmt from './m.js'。一个模块能拥有多个具名导出但不能拥有两个默认导出。具名导出保留了原始标识符,工具链更易检查;默认导出把命名自由交给接收方,可能造成检索不稳定。用在库或长期维护代码时,优先具名;仅在模块主入口和单值场景使用默认。

  • 默认导出每模块只能一个,具名可多个
  • 默认导出的导入名由接收方决定,具名由来源确定
  • 公开主值用默认,成组 API 用具名导出

语法与导入标识符的差异

具名导出的本质是在模块导出表里登记一个标识符。export const parse = s => s.trim() 之后,导入语句必须写 parse 或用 as 改成别名,但不能省略花括号。默认导出则生成名为 default 的特殊入口,接收方写 import p from './m.js' 时,p 就是模块自行决定的一个本地名,源模块内不要求存在同名变量。

两种导出共享同一个导出命名空间,默认导出登记的条目名就是 default。因此冲突只发生在导出名重复时:例如写两个 export default,或同时写 export { x as default } 和 export default y,都会在解析阶段抛出 SyntaxError。而 export default function parse(){} 之后再写 export { parse } 是合法的——前者以 default 为名、后者以 parse 为名,只是让同一个函数从两个名字被引入。默认导出每模块唯一这一约束源自 default 只是普通导出名的规范处理,并非独立的第二个通道。

校验工具库的导出设计

某模块要暴露 isEmail 和 normalizeEmail 两个独立纯函数。如果默认导出整个对象,调用方必须写 import email from './validator' 再加 .isEmail,编辑器无法直接发现可用的函数清单,打包器也有可能因保留对象属性而保留多余代码。改为具名导出后,import { isEmail } from './validator' 精确得到函数且能触发重命名联动。

这个场景里默认导出没有起简化作用,反而增加一层壳。真正需要默认导出的条件是:模块只有一个主要值,且该值不依赖外部继续解构,比如单个 createStore 函数。若预感到会加入 createStoreWithMiddleware,设计时就应用具名或用命名空间对象配合具名导出。

默认导出的可见成本与限制

默认导出的最大限制不是数量,而是丢失规范性的名称。同一个 parse 函数可能被不同文件命名为 parseCsv、load,导致代码库出现同一功能多种叫法,grep 时无法用统一符号定位。因此不建议在公开类库或多人维护项目中满屏默认导出。

一旦模块已经提供默认导出,后续重导出需要专门语法:export { default as Foo } from './a.js' 有效,export default from './a.js' 是语法错误。如果模块包含默认加多个具名,会迫使主要依赖方使用两套导入风格,维护成本上升。没有稳定主值前,保持全部具名可让未来迁移成本最低。

回答前,多想一步

容易答错的地方

默认导出跟 const 声明不搭
不少人写 export default const x = 1,这是 SyntaxError,因为 default 后面可跟表达式或函数/类声明,不能跟带声明关键字的语句。正确为 const x = 1; export default x; 或 export default 1。
默认和具名可共存,但默认只能有一个
ESM 允许 export default main 与 export { helper } 同时出现。真正的坑是重复绑定:export { x as default } 和 export default y 不能同用,因为二者都会登记 default,触发重复导出错误。
试着用自己的话回答

面试官还会怎么问?

什么时候最好不要用默认导出?

当模块的导出会构成工具集、会被远端静态检查或需要按需打包时不要默认导出。默认导出隐藏函数真实名字,不利于重命名和重构,因此标准做法是把核心 API 全部具名导出。

默认导出真的会让 tree-shaking 变差吗?

与打包器有关。默认导出一个对象会使整个对象作为一段被保留,属性级摇树较难;若默认导出的只是纯函数且无副作用,多数打包器可处理。想享受稳定的体积优化,仍优先使用具名导出。

代码规范里怎样统一两种导出?

最小规则是:一个模块只允许一种导出方式,除非默认导出是组件或外部约定的主入口。选择具名还是默认要看模块未来是提供一组能力还是表示一个值,在文件头注释里写明依据。

从一道题,走向一组知识

把知识连起来

模块与语言机制

用 const 和 let 导出的变量在实时绑定上有何区别?

同属「模块与语言机制」专题,接着看 ESM export const 与 let 实时绑定区别 在具体场景中的处理方式。

模块与语言机制

import * as ns 与具名导入在实时绑定和 Tree-shaking 上有什么不同表现?

同属「模块与语言机制」专题,接着看 import * as 与具名导入 tree-shaking 区别 在具体场景中的处理方式。

放回知识体系中复习JavaScript 进阶知识

参考资料

  • export

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 语法与导入标识符的差异
  3. 校验工具库的导出设计
  4. 默认导出的可见成本与限制
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑