深入理解 JavaScript 模块化:export 与 import 全解析

452 阅读4分钟

JavaScript 模块化是现代开发中不可或缺的一部分,它让代码更有条理、更易维护、也更便于多人协作。而 exportimport 是 ES6 提供的标准模块化语法,它们简单易用,但我经常会搞混。今天认真学习了一下,试图彻底掌握 exportimport


什么是模块化?为什么需要模块化?

模块化的概念

模块化就是将代码拆分成多个独立的文件(模块),每个模块完成特定的功能,这样代码更易维护和复用。例如,你可以将一个负责计算的代码放在一个文件中,将与界面相关的代码放在另一个文件中。

模块化的好处

  1. 易维护:将代码拆分后,修改某一部分功能时,不会影响其他部分。
  2. 可复用:模块可以在多个项目中重复使用,避免重复造轮子。
  3. 更清晰的代码结构:每个模块只关注自己的职责,代码更易理解。

ES6 模块化语法:exportimport

在 ES6 中,模块化通过两个核心语法实现:

  1. export:用于导出模块中的变量、函数或类。
  2. import:用于引入其他模块的内容。

我们来看具体的用法。


1. 导出:export

export 用于将模块中的内容导出,使它能够被其他模块使用。我们可以通过两种方式导出内容:默认导出命名导出


默认导出(export default

  • 特点

    • 每个模块只能有一个默认导出。
    • 导入时可以自定义名字,不需要与导出的名字一致。
  • 示例

    假设我们有一个文件 math.js,用于导出一个加法函数:

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

    在另一个文件中,我们可以这样导入它:

    // main.js
    import addFunction from './math.js'; // 可以随意命名
    console.log(addFunction(2, 3)); // 输出:5
    

    注意:文件中只能有一个 export default,否则会报错。


命名导出(export

  • 特点

    • 一个模块可以有多个命名导出。
    • 导入时,名字必须与导出的名字一致(可以通过 as 重命名)。
  • 示例

    假设我们有一个文件 math.js,导出多个函数:

    // math.js
    export function add(a, b) {
      return a + b;
    }
    
    export function subtract(a, b) {
      return a - b;
    }
    

    在另一个文件中,我们可以这样导入:

    // main.js
    import { add, subtract } from './math.js'; // 必须使用与导出相同的名字
    console.log(add(2, 3)); // 输出:5
    console.log(subtract(5, 3)); // 输出:2
    
  • 重命名导入
    如果导出的名字太长或与其他变量冲突,可以用 as 重命名:

    import { add as addition, subtract as subtraction } from './math.js';
    console.log(addition(2, 3)); // 输出:5
    console.log(subtraction(5, 3)); // 输出:2
    

混合使用默认导出和命名导出

你可以在一个模块中同时使用默认导出和命名导出。

  • 示例

    文件 math.js

    export default function multiply(a, b) {
      return a * b;
    }
    
    export function add(a, b) {
      return a + b;
    }
    
    export function subtract(a, b) {
      return a - b;
    }
    

    导入时:

    import multiply, { add, subtract } from './math.js';
    console.log(multiply(2, 3)); // 输出:6
    console.log(add(2, 3));      // 输出:5
    console.log(subtract(5, 3));// 输出:2
    

2. 引入:import

import 用于从其他模块中引入内容。导入的方式与导出的方式密切相关。


引入默认导出

  • 语法

    import anyName from './module.js';
    
  • 示例
    假设文件 math.js 中有一个默认导出:

    export default function add(a, b) {
      return a + b;
    }
    

    我们可以这样导入:

    import addFunction from './math.js'; // 名字可以自定义
    console.log(addFunction(2, 3)); // 输出:5
    

引入命名导出

  • 语法

    import { exportedName } from './module.js';
    
  • 示例
    假设文件 math.js 中有命名导出:

    export function add(a, b) {
      return a + b;
    }
    
    export function subtract(a, b) {
      return a - b;
    }
    

    我们可以这样导入:

    import { add, subtract } from './math.js';
    console.log(add(2, 3));       // 输出:5
    console.log(subtract(5, 3));  // 输出:2
    

引入所有导出内容

可以使用 * 引入模块中所有的命名导出,并将它们绑定到一个对象上。

  • 示例

    import * as math from './math.js';
    
    console.log(math.add(2, 3));       // 输出:5
    console.log(math.subtract(5, 3)); // 输出:2
    

常见问题

1. 默认导出和命名导出不能混淆

如果使用了默认导出,不能用命名导出的语法引入,反之亦然。

// 错误示例:math.js
export default function add(a, b) {
  return a + b;
}

// 错误导入:
import { add } from './math.js'; // 报错:add is not exported

正确方式:

import add from './math.js';

2. 文件路径问题

  • 如果模块和引入文件在不同目录下,路径必须正确。

  • 示例路径:

    • 当前目录:"./module.js"
    • 父目录:"../module.js"
    • 子目录:"./subdir/module.js"

3. 浏览器支持

在 HTML 文件中必须使用 <script type="module"> 才能使用 importexport

<script type="module" src="./main.js"></script>