一、模块化概述
在ES6出现之前,JS不像其他语言拥有“模块化”这一概念,于是为了支持JS模块化
我们使用类、立即执行函数或者第三方插件(RequireJS、seaJS)来实现模块化
但是在ES6出现之后, 上述解决方案都已经被废弃, 因为ES6中正式引入了模块化的概念
ES6模块化模块和NodeJS中一样, 一个文件就是一个模块, 模块中的数据都是私有的
ES6模块化模块和NodeJS中一样, 可以通过对应的关键字暴露模块中的数据, 可以通过对应的关键字导入模块, 使用模块中暴露的数据
隔离不同的js文件,仅暴露当前模块所需要的其他模块,这就是模块化思想。
二、ES6模块化的语法规范
有两种导出方式:常规的导出(每个模块可以导出多次)和 默认的导出(每个模块仅导出一次)。
常规的导出
1. 分开导入导出
export {xxx};
import {xxx} from "path";
例如:
aModule.js
let str = "ES6Module";
export {str};
// 等同于
export let str = "ES6-Module";
index.js
import {str} from "./aModule.js";
console.log(str); // ES6Module
2. 一次性导入导出
export {xxx, yyy, zzz};
import {xxx, yyy, zzz} from "path";
例如:
aModule.js
let name = "lisi";
let age = 20;
function say() {
console.log("hi");
}
export {name, age, say};
index.js
import {name, age, say} from "./aModule";
console.log(name); // lisi
console.log(age); // 20
say(); // hi
3. 更改变量名称
导出和导入时都可以更改变量名称
- 更改导出名称
let str = "ES6-Moudle";
export {str as name};
- 更改导入名称
import {str as name} from "./aModule";
console.log(name);
【注意】
如果是通过
export{xxx};
方式导出数据, 那么在导入接收的变量名称必须和导出的名称一致
这是因为导入的时候本质上是ES6的解构赋值如果是通过
export{xxx};
方式导出数据, 又想在导入数据的时候修改接收的变量名称, 那么可以使用as来修改
但是通过as修改了接收的变量名称, 那么原有的变量名称就会失效export语句输出的接口是对应值的引用,也就是一种动态绑定关系,通过该接口可以获取模块内部实时的值。
export命令规定要处于模块顶层,一旦出现在块级作用域内,就会报错,import同理。
默认的导出
导出数据: export default xxx;
导入数据: import xxx from "path";
例如:
bModule.js
let name = "zs";
export default name;
index.js
import name from "./bModule";
console.log(name); // zs
【注意】
- 如果是通过
export default xxx;
导出数据, 那么在接收导出数据的时候变量名称可以和导出的名称不一样
例如:
bModule.js
let name = "zs";
export default name;
index.js
import res from "./bModule";
console.log(res ); // zs
- 如果是通过
export default xxx;
导出数据, 那么在模块中只能使用一次export default
, 多次无效
两种方式的混合使用
cModule.js
let name = "lisi";
let age = 20;
function say() {
console.log("hi");
}
export {name, age, say};
class Person {
constructor(){
this.name = "ww";
this.age = "33";
}
}
export default Person;
index.js
import Person, {name, age, say} from "./cModule";
let p = new Person();
console.log(p); // Person对象
console.log(name); // lisi
console.log(age); // 20
say(); // hi
使用通配符 *
导出
1. 重新导出其他模块的接口(其实就是转载文件)
aMdule.js
export * from "./bModule";
bModule.js
let str = "ES6-Module";
function say() {
console.log("hi")
}
export {str, say};
index.js
import {str, say} from "./aModule";
console.log(str); // ES6-Module
say(); // hi
个人觉得这种方法有点鸡肋, 需要哪个模块的时候导入哪个模块即可
2. 模块的整体加载
可以使用 *
来指定一个对象,所有输出值都加载到这个对象上:
bModule.js
let str = "ES6-Module";
function say() {
console.log("hi")
}
export {str, say};
index.js
import * as obj from "./bModule";
console.log(obj.str); // ES6-Module
obj.say(); // hi