[TOC] #### 1. 模块的基础用法 --- 定义一个 `module/1.js` 模块: ```javascript let title = '辰风沐阳' let url = 'https://www.itqaq.com/index/art/279.html' function show() { console.log('this is show method') } export { title, url, show } ``` 其中 `type="module"` 表示使用模块化, 允许使用 ES6 模块语法。`./module/1.js` 中的 `./` 不能省略 ``` <script type="module"> import { title, url, show } from "./module/1.js" console.log(title) console.log(url) show() </script> ``` 错误用法示例: ```javascript // 下面代码会报错,因为 es6 要求 export 导出的必须是变量、函数或者类的名称,而不能是一个对象字面量 export { name: 'liang' } ``` #### 2. 模块的延迟解析 --- 因为模块之间会有依赖关系,所以系统在处理模块时会加载全部模块后才会执行模块 所以模块化js代码放在 button 标签之前,也能找到 button 标签 ```html <script type="module"> console.log(document.querySelector('button')) </script> <button>测试</button> ``` #### 3. 模块的作用域 --- 模块有自己的独立作用域,在模块中定义的变量只能在模块内部使用 在模块内部可以使用全局作用域的变量,但在外部则不能使用模块内部的变量,只有使用 `export` 导出才能在外部使用 ``` <script> let title = 'hello' </script> <script> // 模块外部不能使用模块内部的变量,所以 name 是没有值的 console.log(name) // 空值 console.log(title) // hello </script> <script type="module"> // 模块是延迟解析的,变量是否能访问和当前标签页面内容上下没有关系 let name = 'liang' // 模块内部可以访问全局作用域变量,所以能访问到 title console.log({ name, title }) // {name: 'liang', title: 'hello'} </script> ``` #### 4. 模块的预解析 --- 无论模块加载多少次,只会在第一次时产生执行 ```javascript // user.js console.log('load user module'); // 导入多次,控制台输出也只有一次,证明了这个结论 import { } from './user.js'; import { } from './user.js'; import { } from './user.js'; ``` #### 5. 具名导出和导入 --- 具名导出: 顾名思义,就是导出具有名称的成员 ```javascript let site = 'wwww.itqaq.com' function show() { console.log('this is show ') } export { site, show } ``` #### 6. 合并导出的成员 --- 有些模块导出很多成员,如果我们想要接收模块的导出的所有成员,应该怎么做 ? ```javascript // 模块可能是这么导出的 export const title = '标题' export const content = '内容' export default function getInfo() { } // 也可能是这么导出的 const title = '标题' const content = '内容' export default function getInfo() { } export { title, content, getInfo } ``` 可以将模块导出的所有成员合并为一个对象,然后赋值给一个变量 ```javascript import * as user from './user.js'; console.log(user.title); user.default() // 调用默认导出的函数 ``` 虽然提供了批量导入成员的方式,但是并不推荐这么用,推荐用什么成员就接收什么成员 ```javascript import { title } from './user.js'; ``` #### 7. 别名的使用 --- 模块的导入和导出都支持通过 `as` 定义别名,实际开发中用的较多的是导入时定义别名 模块导出成员时定义别名 ```javascript // 如果模块的某个成员名称较长,导出的时候可以使用一个短名称 const getUserInfo = () => { console.log('my name is liang'); } // 导出 getUserInfo 并将名称改为 info export { getUserInfo as info } // 导入时只能是 info,不能用 getUserInfo 了 import { info } from './user.js'; ``` 导入模块时接收成员,并且定义别名 ```javascript export const title = '标题' // 如果已经存在和模块成员相同名称的变量,可以在导入模块成员时定义别名 let title = 'liang' import { title as name } from './user.js'; ``` #### 8. 模块的默认导出 --- `export` 导出数据时使用 `default` 代表时默认导出,那么在导入模块时接收的名称可以任意定义 ```javascript // 默认导出一个函数 export default function show() { console.log('this is show ') } // 导入模块接收时默认可以自定义名称 import api from './modules/show.js' ``` 默认导出本质上是给导出的成员设置了别名 `default`,这也是默认导出只能写一个的原因 ```javascript export { show as default } ``` 接收默认导出的成员,下面两种写法都可以 ```javascript // 常规用法 import user from './modules/show.js'; // 也可以通过 default as 接收默认导出的成员,适合在接收默认导出的同时还接收其他成员时使用 import { default as user, baseUrl } from './modules/show.js'; // 模块示例(一个模块中有默认导出,也有具名导出): export default { title: '标题' } export const baseUrl = 'http://xxx.com/api' ``` 模块有默认导出,导入该模块时才能用使用接收默认导出成员的写法,否则会报错 ```javascript // 导入的模块有默认导出才能这样写,否则会报错 // Uncaught SyntaxError: ... does not provide an export named 'default' import user from './user.js'; ``` 具名导出和默认导出的混合使用及其导入 ```javascript // 模块导出的成员 export const domain = 'https://www.itqaq.com'; export default function request() { return new Promise((resolve, reject) => { }); } // 导入模块,接收成员(下面两种写法都可以) import request, { domain as url } from './modules/request.js'; import { default as request, domain as url } from './modules/request.js'; ``` #### 9. 模块的合并导出 --- 创建一个模块(merge.js)进行合并导出 ```javascript import * as user from './modules/user.js'; import * as admin from './modules/admin.js'; export { user, admin } ``` 导入合并后的模块 ```javascript import * as api from './modules/merge.js'; // 访问方式 // api.user.成员 // api.admin.成员 ```