🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[toc] ### ES6模块化简介 ECMA组织参考了众多社区模块化标准,终于在2015年,随着ES6发布了官方的模块化标准,后成为ES6模块化 ES6模块化具有以下的特点 1. 使用依赖**预声明**的方式导入模块 1. 依赖延迟声明(CommonJS采用的模块加载方式) 1. 优点:某些时候可以提高效率 2. 缺点:无法在一开始确定模块依赖关系(比较模糊) 2. 依赖预声明(ES6采用的模块加载方式) 1. 优点:在一开始可以确定模块依赖关系 2. 缺点:某些时候效率较低 2. 灵活的多种导入导出方式 3. 规范的路径表示法:所有路径必须以./或../开头 ### 基本导入导出 #### 模块的引入 **注意:这一部分非模块化标准** 目前,浏览器使用以下方式引入一个ES6模块文件 ```html <script src="入口文件" type="module"> //不加type="module"为正常引入js文件,文件中用var定义的变量会污染全局变量 //加了type="module"为引入一个模块文件,文件中定义的变量不会污染全局变量 ``` #### 模块的基本导出和导入 ES6中的模块导入导出分为两种: 1. 基本导入导出 2. 默认导入导出 ![](https://img.kancloud.cn/70/b5/70b560a9039d8b4a1d0a2a7b381e972f_901x574.png) #### 基本导出 类似于CommonJS的 ``` exports.xxx = xxxx ``` 基本导出可以有多个,每个必须有名称 基本导出的语法如下: ```js export 声明表达式 //声明表达式必须是新声明的具有声明标识符的语句,如带有var、let、const、function函数名(){}、class类名的语句 ``` ```js export var a = 5; //正确的导出方式。表示导出a,其值为5 //下面三种导出方式均是错误的导出方式 var a = 1; export a; export a = 5; export 5; ``` 或 ```js export {具名符号} ``` ```js //当已经声明了一个变量,导出时又不想改变变量的名称时,即可以使用该方法导出。 let name = 'xiaoming'; //定义了一个变量name let age = 20; //定义了一个变量age export { name, age }; //大括号为导出的一种格式,并不是表示导出一个对象。这条语句表示导出两个变量,name和age,将name变量名称做为导出名称,name的值做为导出的值。 ``` 由于基本导出必须具有名称,所以要求导出内容必须跟上**声明表达式**或**具名符号** #### 基本导入 由于使用的是**依赖预加载**,因此,导入任何其他模块,导入代码必须放置到所有代码之前 对于基本导出,如果要进行导入,使用下面的代码 ```js import {导入的符号列表} from "模块路径" ``` ```js import { name, age } from "./module.js"; //正常导入name和age两个变量 ``` ```js //如果文件中已经定义了name,可以使用as关键字修改导入的变量名 import{ name as name1, age} from "./module.js"; var name = "xiaozhang"; console.log(name, name1); //输出xiaozhang xiaoming ``` ```js //若想导入模块中的所有变量,可以使用*号导入,且必须用as重命名。其会将该导入包装成一个以as重命名为名的对象 import * as person from "./module.js"; console.log(person.name); //输出xiaoming ``` 注意以下细节: - import语句须在文件的最上方书写,多个文件导入写多行import即可。不能在函数体或条件语句中导入。 - 导入时,可以通过关键字```as```对导入的符号进行重命名 - 导入时使用的符号是常量,不可修改 - 可以使用*号导入所有的基本导出,形成一个对象 ```js import "./module.js"; //如果只想执行一下模块中的代码,并不使用模块中导出的任何功能,或模块中本就没有导出任何变量,可以使用上面的语句。即表示执行了一次module.js中的代码。但因为ES6中模块加载有缓存机制,所以同一个模块只有在第一次加载的时候才会执行。这种方式适用于程序的初始化模块,仅在运行程序的时候执行一次,并不需要导出什么功能。 ``` ### 默认导入导出 ![](https://img.kancloud.cn/70/b5/70b560a9039d8b4a1d0a2a7b381e972f_901x574.png) #### 默认导出 每个模块,除了允许有多个基本导出之外,还允许有一个默认导出。 默认导出和基本导出可以同时存在。 默认导出类似于CommonJS中的```module.exports```,由于只有一个,因此无需具名 具体的语法是 ```js export default 默认导出的数据 ``` 或 ```js export {默认导出的数据 as default} ``` 由于每个模块仅允许有一个默认导出,因此,每个模块不能出现多个默认导出语句 #### 默认导入 需要想要导入一个模块的默认导出,需要使用下面的语法 ```js import 接收变量名 from "模块路径" ``` 类似于CommonJS中的 ```js var 接收变量名 = require("模块路径") ``` 由于默认导入时变量名是自行定义的,因此没有别名一说 如果希望同时导入某个模块的默认导出和基本导出,可以使用下面的语法 ```js import 接收默认导出的变量, {接收基本导出的变量} from "模块路径" ``` 注:如果使用*号,会将所有基本导出和默认导出聚合到一个对象中,默认导出会作为属性default存在 ### ES6模块化的其他细节 1. **尽量导出不可变值** 当导出一个内容时,尽量保证该内容是不可变的(大部分情况都是如此) 因为,虽然导入后,无法更改导入内容,但是在导入的模块内部却有可能发生更改,这将导致一些无法预料的事情发生 2. **可以使用无绑定的导入用于执行一些初始化代码** 如果我们只是想执行模块中的一些代码,而不需要导入它的任何内容,可以使用无绑定的导入: ```js import "模块路径" ``` 3. **可以使用绑定再导出,来重新导出来自另一个模块的内容** 有的时候,我们可能需要用一个模块封装多个模块,然后有选择的将多个模块的内容分别导出,可以使用下面的语法轻松完成 ```js export {绑定的标识符} from "模块路径" ``` ![](https://img.kancloud.cn/26/a6/26a658fc4a60605533e9dd3a8ec85d07_992x673.png)