在 JavaScript(特别是 ES6 模块系统)中,export
和 export default
是两种不同的导出方式,它们在语法、使用方式和导入时的行为上有显著区别。以下是详细的对比和说明:
1. 定义和语法
-
export
(命名导出)-
用于导出一个模块中的多个具体命名的值(如变量、函数、类等)。
-
导出的每个值都有一个明确的名称,导入时需要使用相同的名称。
-
示例:
javascriptexport const name = "Alice"; export function sayHello() { console.log("Hello"); }
-
-
export default
(默认导出)-
用于导出一个模块的"默认值",一个模块只能有一个默认导出。
-
默认导出的值没有固定的名称,导入时可以自定义名称。
-
示例:
javascriptexport default function sayHello() { console.log("Hello"); }
-
2. 导入方式
-
export
(命名导出)-
导入时需要使用
{}
并指定具体的名称,名称必须与导出时一致。 -
可以按需导入部分值,也可以使用
* as
导入所有命名导出。 -
示例:
javascript// 文件: module.js export const name = "Alice"; export function sayHello() { console.log("Hello"); } // 文件: main.js import { name, sayHello } from "./module.js"; console.log(name); // "Alice" sayHello(); // "Hello" // 或者导入所有 import * as module from "./module.js"; console.log(module.name); // "Alice"
-
-
export default
(默认导出)-
导入时不需要
{}
,可以自定义名称。 -
一个模块只能有一个默认导出,导入时直接使用
import 自定义名称 from ...
。 -
示例:
javascript// 文件: module.js export default function sayHello() { console.log("Hello"); } // 文件: main.js import greet from "./module.js"; // 名称 "greet" 是自定义的 greet(); // "Hello"
-
3. 数量限制
-
export
(命名导出)-
一个模块可以有多个命名导出,没有数量限制。
-
示例:
javascriptexport const a = 1; export const b = 2; export const c = 3;
-
-
export default
(默认导出)-
一个模块只能有一个默认导出,尝试定义多个会导致语法错误。
-
示例:
javascriptexport default function foo() {} export default function bar() {} // 错误:只能有一个默认导出
-
4. 与 export
结合使用
-
你可以在同一个模块中同时使用
export
和export default
,它们互不冲突。 -
示例:
javascriptexport const name = "Alice"; export default function sayHello() { console.log("Hello, " + name); } // 导入 import greet, { name } from "./module.js"; console.log(name); // "Alice" greet(); // "Hello, Alice"
5. 使用场景
-
export
(命名导出)-
适用于需要导出一组相关功能或值的场景,例如工具模块或常量集合。
-
示例:导出多个工具函数
javascriptexport const add = (a, b) => a + b; export const subtract = (a, b) => a - b;
-
-
export default
(默认导出)-
适用于模块有一个主要功能的场景,通常是模块的核心功能或组件。
-
示例:React 组件
javascriptexport default function MyComponent() { return <div>Hello</div>; }
-
6. 行为差异
-
export
(命名导出)-
导出的值是"实时绑定"的,导入的地方可以感知到值的变化(因为它是引用)。
-
示例:
javascript// module.js export let counter = 0; setTimeout(() => counter++, 1000); // main.js import { counter } from "./module.js"; console.log(counter); // 0 setTimeout(() => console.log(counter), 2000); // 1
-
-
export default
(默认导出)-
默认导出是一个具体的值,导出时会被固定(如果是对象,则是引用)。
-
示例:
javascript// module.js let counter = 0; export default counter; setTimeout(() => counter++, 1000); // main.js import counter from "./module.js"; console.log(counter); // 0 setTimeout(() => console.log(counter), 2000); // 0(不会变化)
-
总结
特性 | export (命名导出) |
export default (默认导出) |
---|---|---|
名称 | 需要指定具体名称 | 无需名称,导入时自定义 |
数量 | 可多个 | 只能一个 |
导入方式 | import { name } from ... |
import anyName from ... |
适用场景 | 导出多个相关值 | 导出模块的主要功能 |
绑定行为 | 实时绑定 | 值固定(对象为引用) |
选择 export
还是 export default
取决于模块的设计需求:
- 如果模块有多个导出,使用
export
。 - 如果模块只有一个主要导出,使用
export default
。 在 React Router v7 中,推荐使用命名导出以适应其约定和工具链要求。