导入导出(Import & Export)

ES6 模块的导入导出方式详解。


📤 导出方式

1. 命名导出(Named Export)

方式一:声明时导出

// math.js
export const PI = 3.14159;
export function add(a, b) {
  return a + b;
}
export class Calculator {
  multiply(a, b) {
    return a * b;
  }
}

方式二:先声明后导出

// math.js
const PI = 3.14159;
function add(a, b) {
  return a + b;
}
class Calculator {
  multiply(a, b) {
    return a * b;
  }
}
 
export { PI, add, Calculator };

方式三:导出时重命名

// math.js
function add(a, b) {
  return a + b;
}
 
export { add as sum }; // 导出时重命名为 sum

2. 默认导出(Default Export)

每个模块只能有一个默认导出:

// utils.js
export default function formatDate(date) {
  return date.toISOString();
}
 
// 或者
function formatDate(date) {
  return date.toISOString();
}
export default formatDate;
 
// 或者导出对象
export default {
  formatDate,
  parseDate
};

默认导出类

// Calculator.js
export default class Calculator {
  add(a, b) {
    return a + b;
  }
}

默认导出值

// config.js
export default {
  apiUrl: 'https://api.example.com',
  timeout: 5000
};

3. 混合导出

// config.js
export const API_URL = 'https://api.example.com';
export const TIMEOUT = 5000;
 
export default {
  version: '1.0.0',
  name: 'MyApp'
};

📥 导入方式

1. 命名导入

导入单个

import { PI, add } from './math.js';

导入全部

import * as math from './math.js';
console.log(math.PI);
console.log(math.add(1, 2));

导入时重命名

import { add as sum } from './math.js';
sum(1, 2); // 使用重命名后的名称

导入多个

import { PI, add, Calculator } from './math.js';

2. 默认导入

import formatDate from './utils.js';
formatDate(new Date());

默认导入和命名导入混合

// config.js
export const API_URL = 'https://api.example.com';
export default {
  version: '1.0.0'
};
 
// 导入
import config, { API_URL } from './config.js';
console.log(config.version);
console.log(API_URL);

重命名默认导入

import { default as formatDate } from './utils.js';
// 或者
import formatDate from './utils.js'; // 更简洁

3. 仅执行模块

// polyfills.js
if (!Array.prototype.includes) {
  Array.prototype.includes = function(item) {
    return this.indexOf(item) !== -1;
  };
}
 
// 导入(仅执行,不导入任何内容)
import './polyfills.js';

🔄 重新导出(Re-export)

重新导出命名导出

// math.js
export function add(a, b) { return a + b; }
export function subtract(a, b) { return a - b; }
 
// index.js(重新导出)
export { add, subtract } from './math.js';
 
// 或者导出全部
export * from './math.js';

重新导出默认导出

// utils.js
export default function formatDate(date) {
  return date.toISOString();
}
 
// index.js
export { default } from './utils.js';
// 或者
export { default as formatDate } from './utils.js';

重新导出并重命名

// math.js
export function add(a, b) { return a + b; }
 
// index.js
export { add as sum } from './math.js';

💡 常见模式

1. 统一导出入口(Barrel Export)

// utils/index.js
export { formatDate } from './date.js';
export { formatCurrency } from './currency.js';
export { formatNumber } from './number.js';
 
// 使用
import { formatDate, formatCurrency } from './utils/index.js';

2. 条件导出

// config.js
const isDev = process.env.NODE_ENV === 'development';
 
export const API_URL = isDev 
  ? 'http://localhost:3000'
  : 'https://api.example.com';

3. 聚合导出

// index.js
export * from './math.js';
export * from './utils.js';
export { default as Calculator } from './calculator.js';

⚠️ 注意事项

1. 导出的是引用,不是值

// counter.js
export let count = 0;
export function increment() {
  count++;
}
 
// app.js
import { count, increment } from './counter.js';
console.log(count); // 0
increment();
console.log(count); // 1(共享同一个 count)

2. 不能重新赋值导入的绑定

// ❌ 错误
import { count } from './counter.js';
count = 10; // TypeError: Assignment to constant variable
 
// ✅ 正确:通过函数修改
import { increment } from './counter.js';
increment();

3. 导入提升

// ✅ 导入会被提升到顶部
console.log(add(1, 2)); // 可以正常使用
import { add } from './math.js';

🔗 相关链接


参考


javascript 模块化 import export es-modules