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