详细全面的讲解javascript中的export、import

 更新时间:2025年09月02日 14:56:59   作者:八九燕来  
JavaScript的ES6模块系统通过export和import实现代码拆分与复用,支持命名导出(多个)、默认导出(一个)及动态导入(按需加载),提升可维护性与性能,需注意环境支持、路径规则及循环依赖等使用细节,本文介绍javascript中的export、import,感兴趣的朋友一起看看吧

在 JavaScript 中,exportimport 是 ES6(ECMAScript 2015)引入的模块系统核心语法,用于实现代码的模块化拆分、复用和依赖管理。它们允许将代码分割到不同文件(模块)中,每个模块专注于特定功能,同时通过 export 暴露内容、import 引入依赖,大幅提升了代码的可维护性和可读性。

一、模块的基本概念

一个 JavaScript 文件就是一个模块(module),模块内部的变量、函数、类等默认是私有的,仅在当前模块内可见。若要让其他模块使用这些内容,必须通过 export 显式暴露;其他模块则通过 import 引入这些暴露的内容。

模块的核心特性:

  • 自动运行在严格模式"use strict")下,避免意外全局变量等问题。
  • 模块内的顶层 thisundefined(非模块脚本中 this 指向全局对象)。
  • 模块是单例的:同一模块被多次导入时,仅执行一次,后续导入复用第一次的结果。
  • 模块加载是异步的,按依赖顺序执行。

二、export:暴露模块内容

export 用于从当前模块向外暴露内容(变量、函数、类等),供其他模块导入。分为两种方式:命名导出(named export)和默认导出(default export)。

1. 命名导出(Named Export)

一个模块可以有多个命名导出,每个导出都有明确的名称,导入时必须使用相同的名称(可重命名)。

语法形式:

直接在声明时导出:

// 导出变量
export const name = "张三";
export let age = 20;
export const arr = [1, 2, 3];
// 导出函数
export function sum(a, b) {
  return a + b;
}
// 导出类
export class Person {
  constructor(name) {
    this.name = name;
  }
}

先声明后集中导出(更推荐,便于维护导出列表):

// 先声明
const name = "张三";
function sum(a, b) {
  return a + b;
}
class Person {}
// 集中导出(使用对象形式,键是导出名称,值是要导出的内容)
export { name, sum, Person };

导出时重命名(避免名称冲突):使用 as 关键字

const name = "张三";
export { name as userName }; // 导出时将 name 重命名为 userName

2. 默认导出(Default Export)

一个模块只能有一个默认导出,通常用于导出模块的“主要内容”(比如一个核心函数或类)。导入时可以自定义名称,无需与导出名称一致。

语法形式:

直接导出(无需名称):

// 导出默认函数
export default function(a, b) {
  return a + b;
}
// 导出默认类
export default class {
  constructor() {}
}
// 导出默认对象
export default {
  name: "张三",
  age: 20
};

先声明后导出(需显式指定 default):

const mainFunction = () => { /* ... */ };
export default mainFunction; // 默认导出 mainFunction

注意: 默认导出本质上是“名称为 default 的命名导出”,只是语法上简化了。

3. 混合导出

一个模块可以同时包含命名导出和默认导出:

// 命名导出
export const version = "1.0.0";
// 默认导出
export default function core() { /* 核心功能 */ }

三、import:导入模块内容

import 用于从其他模块导入已导出的内容,语法需与对应模块的 export 方式匹配。

1. 导入命名导出的内容

需使用大括号 {} 包裹导出时的名称,且名称必须与导出时一致(可通过 as 重命名)。

基本语法:

// 导入 module.js 中的命名导出
import { name, sum, Person } from './module.js';
// 使用导入的内容
console.log(name); // 张三
console.log(sum(1, 2)); // 3
const p = new Person();

重命名导入(避免冲突):

// 导入时将 sum 重命名为 add
import { sum as add } from './module.js';
console.log(add(1, 2)); // 3

2. 导入默认导出的内容

无需大括号,可自定义名称(推荐与模块功能相关的名称)。

基本语法:

// 导入 module.js 的默认导出(假设导出的是一个函数)
import calculate from './module.js'; // calculate 是自定义名称
calculate(1, 2); // 调用默认导出的函数

3. 同时导入默认导出和命名导出

// 导入默认导出(core)和命名导出(version)
import core, { version } from './module.js';
// 使用
core(); // 调用默认导出的核心函数
console.log(version); // 1.0.0

4. 整体导入(命名空间导入)

将模块中所有导出(包括命名导出和默认导出)作为一个对象的属性导入,默认导出会作为 default 属性。

语法:

// 将 module.js 中所有导出合并为一个 module 对象
import * as module from './module.js';
// 使用命名导出的内容
console.log(module.name);
module.sum(1, 2);
// 使用默认导出的内容(默认导出会被放在 default 属性中)
module.default();

5. 仅执行模块(不导入内容)

如果模块仅需要执行副作用(如初始化操作),无需导入其内容,可直接导入:

import './init.js'; // 执行 init.js 中的代码,但不导入任何内容

四、动态导入(Dynamic Import)

ES2020 引入了动态导入语法 import(),与静态 import 不同,它是一个函数,返回一个 Promise,支持在运行时按需加载模块(适合代码分割、懒加载)。

语法:

// 动态导入 module.js,返回 Promise
import('./module.js')
  .then((module) => {
    // 模块加载成功后使用
    console.log(module.name); // 访问命名导出
    module.default(); // 访问默认导出
  })
  .catch((err) => {
    console.error('模块加载失败', err);
  });

配合 async/await 使用(更简洁):

async function loadModule() {
  try {
    const module = await import('./module.js');
    console.log(module.name);
  } catch (err) {
    console.error(err);
  }
}
loadModule();

应用场景:

  • 路由懒加载(如 React Router、Vue Router 中按需加载组件)。
  • 根据条件加载不同模块(如不同环境加载不同配置)。
  • 减少初始加载资源体积,提升性能。

五、模块路径规则

import 后的模块路径需遵循以下规则:

相对路径:导入本地模块时,必须以 ./(当前目录)或 ../(父目录)开头,且通常需要包含文件扩展名(如 .js)。

import { sum } from './utils/math.js'; // 正确
import { sum } from 'utils/math.js'; // 错误(缺少 ./)

绝对路径:从项目根目录或 CDN 导入(较少用):

import { sum } from '/src/utils/math.js'; // 项目根目录
import { sum } from 'https://cdn.example.com/utils.js'; // CDN

第三方模块:导入 npm 安装的包时,直接写包名(无需路径):

import React from 'react'; // 导入 react 包
import axios from 'axios'; // 导入 axios 包

六、使用环境要求

importexport 属于 ES 模块语法,使用时需注意环境支持:

  • 浏览器环境
    • 需在 <script> 标签中添加 type="module" 属性,声明为模块脚本:
  • <script type="module">
      import { sum } from './math.js';
      console.log(sum(1, 2));
    </script>
    
    • 本地开发时需通过服务器(如 localhost)访问,直接打开本地文件(file:// 协议)会因跨域限制报错。
  • Node.js 环境
    • 默认支持 CommonJS 模块(require/module.exports),若使用 ES 模块,需:
    • 将文件扩展名改为 .mjs
    • 或在 package.json 中添加 "type": "module"

七、常见问题与注意事项

  • 默认导出 vs 命名导出
    • 默认导出适合模块的“主要功能”(一个模块一个),导入时名称可自定义。
    • 命名导出适合模块的“辅助功能”(多个),导入时名称必须匹配(可重命名)。
  • 重复导出:同一名称不能重复命名导出,否则报错。
  • 导入不可变:导入的内容是“只读视图”,不能直接修改(但对象属性可改):
  • // module.js
    export let count = 0;
    // 导入后
    import { count } from './module.js';
    count = 1; // 报错(只读)
  • 循环依赖:模块之间循环导入(A 导入 B,B 导入 A)是允许的,但需注意执行顺序可能导致未定义的值。
  • 静态分析:静态 import 必须放在模块顶层(不能在 if、函数等块级作用域中),动态 import() 则可以。

总结

exportimport 是 JavaScript 模块化的核心,通过它们可以实现代码的拆分、复用和依赖管理:

  • export 分为命名导出(多个)和默认导出(一个),用于暴露模块内容。
  • import 需与导出方式匹配,支持命名导入、默认导入、整体导入等。
  • 动态 import() 支持按需加载,适合性能优化。

掌握这些语法能帮助你写出更清晰、可维护的大型 JavaScript 应用。

到此这篇关于详细全面的解说javascript中的export、import的文章就介绍到这了,更多相关js export、import内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 小程序实现多个选项卡切换

    小程序实现多个选项卡切换

    这篇文章主要为大家详细介绍了小程序实现多个选项卡切换,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-06-06
  • 微信小程序实现点击页面出现文字

    微信小程序实现点击页面出现文字

    这篇文章主要介绍了微信小程序实现点击页面出现文字,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-09-09
  • uni-app表单组件(form表单)用法举例

    uni-app表单组件(form表单)用法举例

    平时我们经常会使用到表单,下面这篇文章主要给大家介绍了关于uni-app表单组件(form表单)的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2022-12-12
  • 浅谈TypeScript3.7中值得注意的3个新特性

    浅谈TypeScript3.7中值得注意的3个新特性

    这篇文章主要介绍了TypeScript3.7中值得注意的3个新特性,对TS感兴趣的同学,可以参考下
    2021-05-05
  • JavaScript实现页面跳转的方式汇总

    JavaScript实现页面跳转的方式汇总

    在动手做网站时,不可避免的会碰到页面跳转的问题,新页面是在当前页面打开呢,还是在新窗口打开呢,是不是需要依据参数进行跳转呢或者要经过用户确认后再跳转呢,等等很多种情况,下面我们来看下常用的一些JS实现页面跳转的方式例子,需要的朋友可以参考下
    2016-05-05
  • JavaScript数组方法大全(推荐)

    JavaScript数组方法大全(推荐)

    本文是小编给大家特意整理的关于js数组方法的知识,非常实用,在面试笔试题中经常用得到,有需要的朋友可以参考下
    2016-07-07
  • js 分页全选或反选标识实现代码

    js 分页全选或反选标识实现代码

    分页全选或反选标识 对多选按钮操作。 批量全选添加、批量移除。 行单选添加、移除。 分页之后(全选或不选)状态标识依然存在
    2011-08-08
  • js获取标签元素data-*属性值的4种方法

    js获取标签元素data-*属性值的4种方法

    这篇文章主要分享了js获取标签元素data-*属性值的4种方法,标签上有两个属性​​data-id​​​ 和 ​​data-user-name​​, 需要通过js去获取,下面文章具体介绍需要的小伙伴可以参考一下
    2022-06-06
  • CodeMirror实现代码对比功能(插件react vue)

    CodeMirror实现代码对比功能(插件react vue)

    这篇文章主要介绍了CodeMirror实现代码对比功能,用到的插件有vue或者react都需要这一步且同样的下载方式,本文通过实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2022-05-05
  • JavaScript 继承的实现

    JavaScript 继承的实现

    正因为JavaScript本身没有完整的类和继承的实现,并且我们也看到通过手工实现的方式存在很多问题, 因此对于这个富有挑战性的任务网上已经有很多实现了
    2009-07-07

最新评论