前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
首页程序员面试题库export 列表与声明导出命名冲突
JavaScript模块与语言机制

export { a } 和 export const a 同时写会怎样?怎么避免命名冲突?

会报 SyntaxError。export { a } 和 export const a = 1 都会创建一个叫 a 的导出名,同一个模块里出现两个同名导出是语法错误。解决办法是用 export { a as otherName } 给其中一个改名,或者只用一种形式。

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

两种导出语法的本质

  1. 声明导出export const a = 1,声明变量的同时创建同名导出
  2. 列表导出export { a },引用已有的局部变量创建导出,可以用 as 改名
  3. 冲突规则导出名在模块范围内必须唯一,重复就报语法错误

export { a } 不是导出一个对象。花括号在这里是导出列表的语法,和解构或对象字面量无关。

核心回答

先记住这个答案

export { a } 和 export const a = 1 都会在模块的导出列表里创建一个叫 a 的条目。一个模块不能有两个同名的导出,所以同时写会在解析阶段就报 SyntaxError——代码连执行的机会都没有。解决办法很简单:要么只用其中一种形式,要么用 as 给其中一个导出改个名字。

  • 同名导出是 SyntaxError,不管用哪种语法
  • export { a } 引用已声明的局部变量 a
  • export const a 同时声明变量和创建导出
  • 用 as 重命名解决冲突

两种导出语法的区别

先搞清楚两种写法各自做了什么。声明导出同时做了两件事:声明一个变量,并把它导出。列表导出只做一件事:把一个已经声明好的局部变量导出。

声明导出和列表导出对比JavaScript
// 声明导出:声明 + 导出一步到位
export const count = 0
export function increment() { /* ... */ }

// 列表导出:先声明,再统一导出
const count = 0
function increment() { /* ... */ }
export { count, increment }

// 冲突:两种形式都创建了叫 count 的导出
// export const count = 0
// export { count }  // SyntaxError: Duplicate export 'count'

两种形式最终的效果完全一样——都是创建一个具名导出。唯一的区别是代码组织方式不同。声明导出让你在声明的地方就能看到它是被导出的;列表导出把所有导出集中到一起,模块底部一眼就能看到所有的导出项。

列表导出的真正用途

列表导出的优势在于可以用 as 给导出改名字,以及可以把声明和导出分开管理。

在写 index.js 汇总文件时,列表导出特别有用。从子模块导入具名变量,再用列表导出统一暴露出去,中间可以根据需要重命名。

在汇总文件里用列表导出和重命名JavaScript
// index.js —— 统一出口
import { formatDate } from './date'
import { formatNumber } from './number'

// 如果两个子模块恰好都有一个叫 format 的导出
// 可以在这里用 as 区分
export { formatDate, formatNumber }
// 或者简写成重导出
// export { formatDate } from './date'
// export { formatNumber } from './number'

重导出语法 export { x } from './module' 可以直接把子模块的导出透传出去,不需要先 import 再 export。在写库的入口文件时非常常用。

回答前,多想一步

容易答错的地方

以为 export { a } 是导出一个对象
export { a } 里的花括号不是对象字面量。这是导出列表的专用语法,只能出现在 export 语句里。export { a: 1 } 会报语法错误——这里不支持键值对的写法。
以为重命名之后原名还能用
export { a as b } 之后,导入方只能用 import { b },写 import { a } 会报模块里没有 a 这个导出。不过在源模块内部,局部变量 a 还是叫 a,只是对外暴露的名字变成了 b。
试着用自己的话回答

面试官还会怎么问?

一个模块里最多能有多少个具名导出?

语言规范没有数量限制。你可以在一个模块里导出几百个具名变量,但从代码组织的角度看,如果一个模块的导出太多,通常意味着它承担了太多职责,应该考虑拆分。

export { } 空列表合法吗?

合法。export {} 不导出任何东西,但它让这个文件被识别为一个 ESM 模块。在 TypeScript 里,有时候一个文件没有 import 也没有 export,TypeScript 会把它当成全局脚本而不是模块。加一个 export {} 就能告诉 TypeScript 这是一个模块。

重导出时可以改名吗?

可以。export { formatDate as format } from './date' 把 date 模块的 formatDate 以 format 的名字重新导出。导入方用 import { format } from './index' 就行。重导出加重命名在写库的公共 API 时很常见,可以在不改内部实现的前提下调整对外暴露的名字。

从一道题,走向一组知识

把知识连起来

模块与语言机制

原生 ESM 怎么导入 JSON?导入语句后面的 with 属性起什么作用?

了解导出的命名规则后,再看 JSON 模块的导入导出会更清楚为什么 JSON 只能作为默认导出。

模块与语言机制

import map 是干什么的?有了它浏览器怎么解析 import 'vue'?

Import Map 解决的是模块路径映射问题,和导出命名冲突属于模块系统的不同层面。

参考资料

  • JavaScript:模块与语言机制参考资料

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

本题目录
  1. 先记住这个答案
  2. 两种导出语法的区别
  3. 列表导出的真正用途
  4. 容易答错的地方
  5. 面试官还会怎么问
  6. 把知识连起来
读懂,再试着讲出来

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

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