ESModule.js
模块化:在解决一些复杂问题的同时,按照一种分类的思想,把问题分解成若干个小模块功能,然后逐个实现这些小模块
模块化系统应该做什么?
- 封装定义一个模块
- 导出内容供其他模块使用
- 能够导入其他模块的内容
CommonJS Node.js 的模块化规范 :module.exports / require()
AMD require.js 异步模块化标准
ESModule ES6 新增的模块化规范
- 一个 js 文件就是一个模块
- export 关键字 导出
- import 关键字 导入
1. export 导出
单个导出
// export 关键字用于指定模块导出的内容// 单个导出export var name = 'mabin';export var age = 18;export var job = 'FE';export let x = 1;export const y = 2;export function sum(a, b) {return a + b;}export class Teacher {constructor(name, age) {this.name = name;this.age = age;}}let ok = 100;// 单个导出 export 变量声明语句;
批量导出
var name = 'mabin';var age = 'age';var job = 'FE';let x = 1;const y = 2;function sum(a, b) {return a + b;}class Teacher {constructor(name, age) {this.name = name;this.age = age;}}let ok = 100;// 批量导出: export {要导出的变量}export {name, age, job, x, y, sum, Teacher}// 推荐使用批量导出的方式导出,可以很清晰的看出模块导出了哪些东西;
2. export
import 关键字用来从其他模块中导入内容,导入注意事项:
- import {变量} from ‘带路径的模块文件’
- 模块没有导出的的变量不能导入
- html 在引入模块化的 js 文件时,script 标签上要写 type = “module”
例子:
// 导入 4-export.jsimport {name, age, job, x, y, sum, Teacher} from "./4-export.js";
写在 import 后面的花括号中的都是变量,自己声明的变量不能喝花括号里面的重名
as 关键字
在导入的时候给导出的变量重命名:as 关键字
语法:import {原名 as 新名字} from 模块
import {Teacher as T} from "./5-export.js";// console.log(Teacher); 重命名之后 Teacher 就不能用了console.log(T);// 按需导入,不需要全部导入
全部导入
全部导入:把模块中导出的内容全部导入进来
import * as obj from './5-export.js'; // 把 5-export.js 中导出的内容全部导入,放到 obj 中,obj 是一个对象;obj 是一个变量,符合变量命名的变量都行;console.log(obj); // obj 是一个对象,对象中的属性名是导出时的变量名,属性的值是导出时变量所代表的值;console.log(obj.sum(3, 4));
默认导出
在前面的例子中,我们想要导入,必须知道导出的时候名字都是什么,如果不知道没办法导入;ESModule 提供了一个默认导出,其他模块在导入的时候可以不关心导出的名字是什么
export default function sum(a, b) {return a + b;}一个模块的默认导出只能有一个,多了要报错// export default function minus(a, b) {// return a - b;// }console.log(`1111`);import aaa from './9-export-default.js';console.log(aaa);// 如果模块是默认导出的,导入的时候不要写花括号,导入时的名字随意写;
3. 动态导入
动态导入:import 只能是同步的,模块导入是静态的,发生在 js 代码执行之前,而且只能写在顶层作用域中;但是有一些场景需要动态导入模块;此时我们需要用 import()方法
import() 方法支持动态导入,返回一个 Promise 实例,可以直接 .then,then 的第一个回调收到的参数就是模块中的内容
动态导入就是想在什么地方导入就在什么地方导入,想什么时候导入就什么时候导入
// 3s 后导入setTimeout(() => {import('./5-export.js').then((res) => {console.log(res);})}, 3000);let ran = Math.round(Math.random() * (10 - 0) + 0);console.log(ran);// 如果随机数大于5去加载 a 模块,否则加载 b 模块if (ran > 5) {import('./a.js').then((a) => console.log(a))} else {import('./b.js').then((b) => console.log(b));}// 动态导入模块的场景:// 1. 按需加载,如点击或者滑动的时候去加载;// 2. 条件加载,条件为 true 的时候加载 a 模块,否则加载 b 模块// 3. 模块的路径是动态的,例如路径是通过 ajax 从服务端获取的// 动态加载多个模块: Promise.all([])Promise.all([import('./a.js'),import('./b.js')]).then((arr) => {console.log('L 39');console.log(arr);});// import() 和 async / await// import() 会返回 promise 对象async function getM() {let A = await import('./a.js');let B = await import('./b.js');return [A, B]}getM().then((res) => {console.log('L51');console.log(res);});// a 模块export let a = 'A';// b 模块export let b = 'B';
