兰 亭 墨 苑
期货 · 量化 · AI · 终身学习
首页
归档
编辑文章
标题 *
URL 别名 *
内容 *
(支持 Markdown 格式)
我们来详细解析 JavaScript ES6 模块中的 `export` 和 `import`。 `export` 和 `import` 是 ES6 模块系统的核心,它们使得 JavaScript 代码可以被分割成可重用的、独立的文件(模块),极大地改善了代码的组织结构、可维护性和依赖管理。 ### **核心概念** * **模块化**: 每个文件就是一个独立的模块。 * **独立作用域**: 每个模块内部都有自己的作用域,模块内的变量、函数、类在外部默认是不可见的。 * **静态解析**: `import` 和 `export` 命令只能在模块的顶层使用,不能在代码块(如 `if` 语句)或函数内部使用。这是因为 ES6 模块在编译时(静态地)就能确定模块的依赖关系,以及导入和导出了哪些变量。 --- ### **`export`:从模块中导出** `export` 命令用于规定模块的对外接口。一个模块可以有多个 `export`。导出方式主要分为两种:**命名导出(Named Exports)** 和 **默认导出(Default Export)**。 #### 1. **命名导出 (Named Exports)** 命名导出允许你用指定的名字导出一个或多个变量、函数或类。 **方式一:在声明时直接导出** ```javascript // a.js export const name = 'Alice'; export let age = 25; export function sayHello() { console.log('Hello!'); } export class User { constructor(name) { this.name = name; } } ``` **方式二:使用大括号统一导出** 这种方式更加清晰,可以一目了然地看到模块导出了哪些内容。 ```javascript // b.js const name = 'Bob'; function sayGoodbye() { console.log('Goodbye!'); } // 在文件末尾统一导出 export { name, sayGoodbye }; ``` **方式三:导出时重命名** 如果你想用不同的名字导出,可以使用 `as` 关键字。 ```javascript // c.js function greet() { console.log('Greetings!'); } // 将 greet 函数以 hi 的名字导出 export { greet as hi }; ``` #### 2. **默认导出 (Default Export)** 每个模块只能有一个默认导出。默认导出时,导入方可以为其指定任意名称。这对于模块只提供单一功能或主要功能的场景非常方便。 ```javascript // d.js export default function() { console.log('This is the default export.'); } // 或者导出一个类 // export default class User { ... } // 或者导出一个变量 // const myConfig = { ... }; // export default myConfig; ``` **注意**: `export default` 后面跟的是一个值(表达式),所以不能写成 `export default const name = '...';`,而应该写成 `const name = '...'; export default name;`。 #### 3. **混合使用** 一个模块可以同时使用命名导出和默认导出。 ```javascript // e.js export default function mainFunction() { // ... } export const version = '1.0'; export function helper() { // ... } ``` --- ### **`import`:从模块中导入** `import` 命令用于加载其他模块提供的功能。 #### 1. **导入命名导出的模块** 导入命名导出的成员时,必须使用大括号 `{}`,并且变量名必须与导出时的名称一致。 ```javascript // main.js import { name, sayHello } from './a.js'; console.log(name); // 'Alice' sayHello(); // 'Hello!' ``` **导入时重命名** 如果导入的变量名与当前作用域的变量冲突,或者你想要一个更具描述性的名字,可以使用 `as` 关键字。 ```javascript // main.js import { name as userName, sayHello as greet } from './a.js'; console.log(userName); // 'Alice' greet(); // 'Hello!' ``` #### 2. **导入默认导出的模块** 导入默认导出的成员时,不需要使用大括号,并且可以为其指定任意名称。 ```javascript // main.js import myCustomFunction from './d.js'; myCustomFunction(); // 'This is the default export.' ``` #### 3. **导入所有命名导出的成员(通配符 `*`)** 你可以使用星号 (`*`) 将一个模块中所有命名导出的成员作为一个对象导入。 ```javascript // main.js import * as utils from './a.js'; // utils 是你自定义的对象名 console.log(utils.name); // 'Alice' utils.sayHello(); // 'Hello!' console.log(utils.age); // 25 ``` **注意**: `import *` 不会包含 `export default` 导出的成员。 #### 4. **混合导入** 当一个模块同时有默认导出和命名导出时,可以这样导入: ```javascript // main.js import mainFunc, { version, helper } from './e.js'; mainFunc(); console.log(version); // '1.0' helper(); ``` `mainFunc` 是对 `e.js` 模块默认导出的引用,`{ version, helper }` 是对命名导出的引用。 #### 5. **仅执行模块(副作用导入)** 有时你可能只想执行一个模块中的代码,而不需要导入任何东西(例如,这个模块可能只是向 `window` 添加了一些 polyfill)。这种情况下,可以直接 `import` 该文件。 ```javascript // main.js import './polyfill.js'; // 仅执行 polyfill.js 文件中的代码 ``` --- ### **`export ... from`:模块的转发** 这个语法可以将另一个模块的接口聚合到当前模块中,并直接导出,而无需先 `import` 再 `export`。 **转发命名导出** ```javascript // aggregator.js // 将 a.js 中的 name 和 sayHello 导出 export { name, sayHello } from './a.js'; // 转发时重命名 export { hi as greet } from './c.js'; ``` **转发所有命名导出** ```javascript // aggregator.js export * from './b.js'; // 转发 b.js 的所有命名导出 ``` **转发默认导出** 转发默认导出需要显式命名。 ```javascript // aggregator.js export { default as myDefaultFunction } from './d.js'; ``` **注意**: `export * from './module.js'` 不会转发 `module.js` 的默认导出。 ### **总结与关键点** | 特性 | `export` (导出) | `import` (导入) | | :--- | :--- | :--- | | **类型** | **命名导出** (`export { a }`) / **默认导出** (`export default b`) | **命名导入** (`import { a }`) / **默认导入** (`import b`) | | **数量** | 命名导出可有多个,默认导出只能有一个。 | 可以同时导入命名和默认成员。 | | **命名** | 命名导出必须使用导出时的名字;默认导出不需要。 | 命名导入必须使用导出时的名字(可用 `as` 重命名);默认导入可任意命名。 | | **语法** | `export { a }` / `export default b` | `import { a } from '...'` / `import b from '...'` | | **静态性** | 编译时确定接口,只能在顶层作用域使用。 | 编译时确定依赖,只能在顶层作用域使用。 | | **绑定** | 导出的是值的**动态只读引用**(Live Binding)。如果模块内部的值改变,`import` 导入的值也会跟着改变。 | 导入的变量是**只读**的,不能在当前模块中重新赋值。 | 掌握 `import` 和 `export` 是现代 JavaScript 开发的基础。它们不仅让代码更加结构化,也是 Webpack、Rollup 等构建工具进行 Tree Shaking(摇树优化,移除未使用的代码)的技术基础。
配图 (可多选)
选择新图片文件或拖拽到此处
标签
更新文章
删除文章