ES6 模块:导入与导出
在本节课中,我们将介绍 ES6 中导入和导出模块功能的各种方式。
在 JavaScript ES6 中,你可以从模块中导入和导出功能。这些功能可以是函数、类、组件、常量等任何可以赋值给变量的内容。模块可以是一个单独的文件,也可以是一个包含一个入口文件(通常是 index 文件)的文件夹。
在我们最初使用 create-react-app 启动应用时,就已经在初始文件中使用了多个 import 和 export 语句。import 和 export 语句帮助你在多个文件之间共享代码。历史上,JavaScript 环境中已有多种解决方案来实现这一功能,但由于缺乏统一的标准方法,导致情况混乱。最终,JavaScript ES6 将其作为原生特性引入。
这些语句支持代码拆分,即将代码分布在多个文件中,以保持其可重用性和可维护性。前者成立是因为我们可以将一段代码导入到多个文件中;后者成立是因为代码只在一个地方进行维护。
我们还应考虑代码封装,因为并非所有功能都需要从文件中导出。某些功能应仅限于定义它们的文件内部使用。文件的导出本质上是该文件的公共 API,只有被导出的功能才能在其他地方被复用。这符合封装的最佳实践。
以下示例展示了如何通过两个文件共享一个或多个变量。最终,这种方法可以扩展到多个文件,并且能够共享远不止简单变量的复杂内容。
导出一个或多个变量的操作称为命名导出:
1// file1.js 2const firstname = 'Robin'; 3const lastname = 'Wieruch'; 4 5export { firstname, lastname };
然后在另一个文件中,通过相对路径导入这些变量:
1// file2.js 2import { firstname, lastname } from './file1.js'; 3 4console.log(firstname); 5// 输出:Robin
你还可以将另一个文件中所有导出的变量作为一个对象整体导入:
1// file2.js 2import * as person from './file1.js'; 3 4console.log(person.firstname); 5// 输出:Robin
导入时可以使用别名,这在从多个文件导入具有相同命名导出的功能时非常必要:
1// file2.js 2import { firstname as username } from './file1.js'; 3 4console.log(username); 5// 输出:Robin
此外还有 default 语句,适用于以下几种情况:
- 导出和导入单一功能
- 突出模块导出 API 的主要功能
- 提供默认导入的备用机制
1// file1.js 2const robin = { 3 firstname: 'robin', 4 lastname: 'wieruch', 5}; 6 7export default robin;
导入默认导出时,必须省略大括号:
1// file2.js 2import developer from './file1.js'; 3 4console.log(developer); 5// 输出:{ firstname: 'robin', lastname: 'wieruch' }
导入名称可以与默认导出名称不同,并且可以与命名导出和导入语句结合使用:
1// file1.js 2const firstname = 'robin'; 3const lastname = 'wieruch'; 4 5const person = { 6 firstname, 7 lastname, 8}; 9 10export { 11 firstname, 12 lastname, 13}; 14 15export default person;
在另一个文件中导入默认导出或命名导出:
1// file2.js 2import developer, { firstname, lastname } from './file1.js'; 3 4console.log(developer); 5// 输出:{ firstname: 'robin', lastname: 'wieruch' } 6console.log(firstname, lastname); 7// 输出:robin wieruch
你也可以省略多余行,直接在 file1.js 中对命名导出的变量进行声明:
1import { firstname, lastname } from './file1.js'; 2 3console.log(firstname); 4console.log(lastname);
这些是 ES6 模块的主要功能。它们帮助你组织代码、便于维护,并设计可重用的模块化 API。你还可以导出和导入功能用于测试,这将在后续章节中进行实践。